简体   繁体   中英

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?

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
    }
}

It's a bit clumsy, but this code works. I'll take your suggestions, and get rid of the Trim mess.

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

if ($driveI -eq $null)  {

    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 ($testdrv -eq $null)
        {
            $s = $s.Trim([char]0x0027)
            Set-WmiInstance -input $driveI -Arguments @{DriveLetter=$s}
            Write-Host I: has been moved to $s
            break
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM