Search code examples
stringpowershellwmiwmic

Passing string variable as Argument in Powershell


I'm trying to write a PowerShell script to change drive letter of I: to something else. Here's the script.

$driveI = Get-WmiObject -Class win32_volume -Filter "DriveLetter='I:'"

if ($driveI.SerialNumber=""){

    write-host "I: is free..."

}   else  {

    write-host "I: is occupied"
    foreach ( $s in @("'Z:'", "'Y:'", "'X:'", "'W:'", "'V:'", "'U:'", "'T:'", "'R:'", "'Q:'", "'P:'", "'O:'", "'N:'", "'M:'", "'L:'", "'K:'", "'J:'", "'H:'", "'G:'", "'F:'", "'E:'", "'D:'", "'B:'", "'A:'"))
    {
        $testdrv = Get-WmiObject -Class win32_volume -Filter "DriveLetter=$s"

        if (!$testdrive.Exist)
        {
            $s = '"'+$s.Trim([char]0x0027)+'"'
            Set-WmiInstance -input $driveI -Arguments @{DriveLetter=$s}
            Write-Host I: has been moved to $s
            break
        }
    }
}

Allow me to walk you through the script. $driveI is used to retrieve all information regarding I:. Now, if I: has no serial number, it indicates that I: doesn't exist. If, on the other hand, I: exists, I'm trying to find a drive letter which is free. I'm implementing my search with the foreach loop. Now, when we call Get-WmiObject, we use drive letters with single quote. But when we use Set-WmiInstance, we use double quotes. However, even when I modify $s to be wrapped by double quote, it doesn't work. In short, if I use Write-Host $s, I get in output, say, "E:". When I use Set-WmiInstance -input $driveI -Arguments @{DriveLetter="E:"}, it works. But when I use Set-WmiInstance -input $driveI -Arguments @{DriveLetter=$s}, it doesn't work. Could anyone tell me what I'm doing wrong?


Solution

  • Don't put quotes in strings when you're going to remove them later anyway. Instead add the quotes where you actually need them:

    $driveLetters = 'Z:', 'Y:', 'X:', ..., 'D:', 'B:', 'A:'
    foreach ( $s in $driveLetters ) {
        $testdrv = Get-WmiObject -Class Win32_Volume -Filter "DriveLetter='$s'"
    
        if (-not $testdrv) {
            Set-WmiInstance -input $driveI -Arguments @{DriveLetter=$s}
            Write-Host "I: has been moved to $s"
            break
        }
    }