我有一个脚本,用于检查是否存在带有某些字母的驱动器。 如果该字母存在,它将删除这些字母。 然后该脚本根据其“标签”查找驱动器,并根据脚本中指定的内容更改其字母。
我正在寻找完善的脚本,以便在第一部分中它将查找带有字母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:\Windows\Temp\FixPartitionsLog.txt -Append
Set-WmiInstance -input $FileServerPartition -Arguments @{DriveLetter="E:"} | Out-File -FilePath C:\Windows\Temp\FixPartitionsLog.txt -Append
}
Catch
{
$ErrorMessage = $_.Exception.Message | Out-File -FilePath C:\Windows\Temp\FixPartitionsLog.txt
}
sleep 5
Restart-Service server -Force
答案 0 :(得分:1)
这是我最后使用的解决方案:
$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:\Windows\Temp\FixPartitionsLog.txt -Append
Set-WmiInstance -input $FileServerPartition -Arguments @{DriveLetter="E:"} | Out-File -FilePath C:\Windows\Temp\FixPartitionsLog.txt -Append
}
Catch
{
$ErrorMessage = $_.Exception.Message | Out-File -FilePath C:\Windows\Temp\FixPartitionsLog.txt
}
sleep 5
Restart-Service server -Force
答案 1 :(得分:0)
我已经有一个函数可以执行您想要的操作。
我原样包含了它,但实际上只需要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 Cmdlet更快,
但是有理由在没有其他方法之前不要混合使用它们。