Powershell 检查驱动器号是否存在,如果存在,则删除



我有一个脚本来检查是否有带有某些字母的驱动器。 如果该字母存在,它将删除这些字母。 然后,脚本根据驱动器的"标签"查找驱动器,并根据脚本中指定的内容更改驱动器的字母。

我希望完善脚本,以便在第一部分中查找任何带有字母 E 或 D 的驱动器,如果是,请删除它们。 如果没有找到,那么只需根据磁盘的标签转到更改的第二部分。

Get-Volume -DriveLetter E | Get-Partition | Remove-PartitionAccessPath -AccessPath E:
Get-Volume -DriveLetter D | Get-Partition | Remove-PartitionAccessPath -AccessPath D:
$DataPartition = Get-WMIObject Win32_Volume | where{ $_.Label -eq 'Data'}
$FileServerPartition = Get-WMIObject Win32_Volume | where{ $_.Label -eq 'FileServer'}
$DataPartition.DriveLetter = $null
$DataPartition.Put()
$FileServerPartition.DriveLetter = $null
$FileServerPartition.Put()

Try
{
Set-WmiInstance -input $DataPartition -Arguments @{DriveLetter="D:"} | Out-File -FilePath  C:WindowsTempFixPartitionsLog.txt -Append
Set-WmiInstance -input $FileServerPartition -Arguments @{DriveLetter="E:"} | Out-File -FilePath  C:WindowsTempFixPartitionsLog.txt -Append
}
Catch
{
$ErrorMessage = $_.Exception.Message | Out-File -FilePath C:WindowsTempFixPartitionsLog.txt
}
sleep 5
Restart-Service server -Force

这是我最后使用的解决方案:

$driveLetters= (Get-Volume).DriveLetter
if ($driveLetters -contains "d" -or $driveLetters -contains "e")
{
switch ($driveLetters)
{
"d" {Get-Volume -DriveLetter D | Get-Partition | Remove-PartitionAccessPath -AccessPath D:}
"e" {Get-Volume -DriveLetter E | Get-Partition | Remove-PartitionAccessPath -AccessPath E:}
}
}
$DataPartition = Get-WMIObject Win32_Volume | where{ $_.Label -eq 'Data'}
$FileServerPartition = Get-WMIObject Win32_Volume | where{ $_.Label -eq 'FileServer'}
$DataPartition.DriveLetter = $null
$DataPartition.Put()
$FileServerPartition.DriveLetter = $null
$FileServerPartition.Put()

Try
{
Set-WmiInstance -input $DataPartition -Arguments @{DriveLetter="D:"} | Out-File -FilePath  C:WindowsTempFixPartitionsLog.txt -Append
Set-WmiInstance -input $FileServerPartition -Arguments @{DriveLetter="E:"} | Out-File -FilePath  C:WindowsTempFixPartitionsLog.txt -Append
}
Catch
{
$ErrorMessage = $_.Exception.Message | Out-File -FilePath C:WindowsTempFixPartitionsLog.txt
}
sleep 5
Restart-Service server -Force

我已经有一个函数在做你想做的事。
我按原样包含了它,但您实际上只需要其中的 5 行。
而且和你问的略有不同。 仅删除找到的标签的字母。
例如,如果未找到"数据"标签,但存在"D:\",则不会删除字母"D"。

[CmdletBinding()]
param()
function Set-Partition_NewDriveLetter_Force {
param(
[Parameter(ValueFromPipeline = $true)][Alias('InputObject')]
$DiskPartition,
[Parameter(Mandatory = $true)]
[System.Char]$NewDriveLetter
)
# if (Test-Path -LiteralPath "${NewDriveLetter}:") { # will error if letter does not exist
# if (Get-Volume -DriveLetter $NewDriveLetter) {      # will error if letter does not exist
if (Get-Volume -FilePath "${NewDriveLetter}:") {
if ($DiskPartition.DriveLetter -ne $NewDriveLetter) {
Write-Verbose "Letter $NewDriveLetter is already taken by other volume, removing and adding to detected volume..."
Remove-PartitionAccessPath -DriveLetter $NewDriveLetter -AccessPath "${NewDriveLetter}:"
Set-Partition -InputObject $DiskPartition -NewDriveLetter $NewDriveLetter
} else { Write-Verbose "Letter $NewDriveLetter is already assigned to this volume." }
} else {
Write-Verbose "Letter $NewDriveLetter is being assigned to detected volume."
Set-Partition -InputObject $DiskPartition -NewDriveLetter $NewDriveLetter
}
}

foreach ($p in Get-Volume | Where-Object { $_.FileSystemLabel -in 'Recovery', 'SYSTEM' }) {
Write-Host "Found drive with Label: $($p.FileSystemLabel)"
switch ($p.FileSystemLabel) {
'Recovery' { $p | Get-Partition | Set-Partition_NewDriveLetter_Force -NewDriveLetter 'R' }
'SYSTEM' { $p | Get-Partition | Set-Partition_NewDriveLetter_Force -NewDriveLetter 'S' }
}
}

用:

如果将其保存到 ps1 文件并使用-Verbose参数调用,它将显示更多输出。

解释:

我命名了该函数,并包含类似于执行类似函数的 Cmdlet 的参数。

前两行为脚本块启用"高级功能"。只有-Verbose工作才需要它。

从评论中可以看出,如果不存在卷号,Get-Volume -FilePath 'X:'是我发现的唯一不出错的方法。 如果没有字母,(Get-Volume).DriveLetter也会出错,但这不太可能。

我限制了磁盘查询的数量,尽管这实际上可能不会获得太多速度。

注意您的答案:

你不需要if ($driveLetters -contains "d" -or $driveLetters -contains "e")当它后跟switch时,在这种情况下,这也是一个条件语句,执行相同的工作。

您不需要 Get-Volume 和 Get-Partition,因为 Get-Partition 也有 -DriveLetter 参数:
"d" { Get-Partition -DriveLetter D | Remove-PartitionAccessPath -AccessPath D: }

不需要 WMI 来读取标签,Get-Volume 具有 Label 属性。
有时,直接使用 .NET 或 WMI 可能更快,而不是调用 PS Cmdlets, 但是有理由不混合这些,直到没有其他方法。

相关内容

最新更新