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

时间:2018-11-01 17:45:18

标签: 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:\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

2 个答案:

答案 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更快, 但是有理由在没有其他方法之前不要混合使用它们。