У меня уже была функция, выполняющая то, что вы хотите.
Я включил его как есть, но на самом деле вам нужно всего 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
, он покажет больше вывода.
Пояснение:
Я назвал функцию и включил параметры, похожие на командлет, выполняющий аналогичную функцию.
Первые две строки включают «расширенную функцию» для блока скрипта. Это нужно только для работы -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,
но есть причины не смешивать их, пока нет другого пути.