Reputation: 77
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?
Upvotes: 1
Views: 4511
Reputation: 77
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
}
}
}
Upvotes: 0
Reputation: 200293
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
}
}
Upvotes: 3