PowerShell: Get Drive Letters for iSCSI Targets

By | December 1, 2019

This wasn’t something I had really though about until I came across an Environment where they had multiple iSCSI targets on a SAN with very similar names. Each target was hosting a VHDX for Virtual machines. The problem arose when I was tasked with removing the old iSCSI target.

On first thought, I said this was easy, write a PowerShell script to get all the locations for all the VM’s VHD’s which will include the drive letter, then disconnect the iSCSI target. Get the locations I did. Recognised which drives were in use and which ones could be removed.

Now it was time to disconnect the iSCSI targets. Into the iSCSI initiator and all I could see was the iSCSI TargetNodeAddress, no drive letters. This sent me on a quest to have an easy way to obtain iSCSI Node Address and Drive letters.

I decided to write a PowerShell script for this which can be found below, and also on GitHub. The script will run through all iSCSI connections and get their associated drive letters with the option to export this to CSV.

https://github.com/decturau/PowerShell/blob/master/Windows/Get%20iSCSI%20Connections%20Drive%20Letter%20and%20Export.ps1

# Script Created by Declan T
# The purpose of this script is to obtain all iSCSI connections and obtain the Disk, Drive Letter and TargetNodeAddress. This also gives you the option to export to csv. 

#Run this script as administrator (Must be local admin)
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }

# Create a function for gathering data
Function GatherInfo {
    # Declare the disk variable so we can get the DiskNumber and Drive Letter
    $Disks=Get-Partition | Select -ExpandProperty DiskNumber

    # Take each disk number and get drive letter and iSCSI conenctions from variables
    Foreach ($disk in $disks) {
	    $Partition= Get-Partition -DiskNumber $Disk
        $ISCSI = Get-Disk -Number $Disk | ?{$_.BusType -Eq "iSCSI"} | Get-IscsiSession 
    
	    # Custom Output based on variables
        [pscustomobject]@{
            DiskNumber=$Partition.DiskNumber -join ''; 
            DriveLetter=($Partition.DriveLetter -join ''); 
            TargetNodeAddress=$ISCSI.TargetNodeAddress -join '';
 
        }  
    }
}

# Clear the screen and promt the user if they wish to export results to csv 
Clear-Host
Write-Host 'You can Export this to CSV. If you select No (default) it will display results in console.' -ForegroundColor Yellow
$Export=Read-Host 'Do you wish to export these results to CSV? (Y/N)'

# If statement based on user input. If Y then it will ask for a path. Anything else will run the script in the console. 
If ($Export -eq "Y") {
    Write-Host 'Filepath MUST BE VALID' -ForegroundColor Yellow 
    $Location=Read-Host 'Enter a Valid Export path (Including Filename). E.g. C:\temp\export.csv' 
    % {Write-Host "Getting your data. Please wait."; GatherInfo | Export-Csv -Path $Location}
    Write-Host 'Complete. Your CSV is in the path you specified, provided it was valid.'
    Read-Host 'Press Enter to Exit'
    }    

Else {
    % {Write-Host "Getting your data. Please wait."; GatherInfo | Out-Host }
    Read-Host 'Press Enter to Exit'
     } 

In my case all iSCSI targets were a located on a SAN.