分配固定驱动器号在Windows Server上的USB设备(2012)

问题描述:

你好老乡Stackoverflowers :)分配固定驱动器号在Windows Server上的USB设备(2012)

我寻找各种方法来分配驱动器号固定到USB驱动器的Windows Server 2012(基础)上。

方案: 我的一个较小的客户有2个USB驱动器用于他的服务器备份,每天都有一个交换机进行异地备份。目前,如果存在不匹配情况,他们将手动重新分配Drivelet。

我已经有了一个计划来实现它,但想在实施它之前征求建议,因为我不确定这是最好的解决方案。

我会去了解它的方式如下:

  1. 启用DriverFramework-用户模式日志如果未启用
  2. 创建由事件ID 2106
  3. 运行PowerShell脚本触发计划任务(通过如果设备ID相匹配的备份驱动器

之一分配驱动器号的计划任务),所以现在的问题是:

以某种方式可以将固定驱动器号分配给一组USB设备,而无需在每次连接设备时都运行脚本?

如果没有,是否有更好的方法来检测设备何时连接并触发任务?

当然,我做了一些研究,但只找到Windows7或Server2008的解决方案。我宁愿在没有第三方工具的情况下解决此问题。

预先感谢您对您能在这个话题给任何见解

问候保罗

我不知道如果这能帮助很多,但我发现了一个不错的职位在https://social.technet.microsoft.com/Forums/windowsserver/en-US/09c9814a-38fa-4b16-bc8f-01329882a791/powershell-wmi-get-usb-storage-devices-only在下面的代码帮助检测到连接的USB设备:

$diskdrive = gwmi win32_diskdrive | ?{$_.interfacetype -eq "USB"} 
$letters = $diskdrive | %{gwmi -Query "ASSOCIATORS OF {Win32_DiskDrive.DeviceID=`"$($_.DeviceID.replace('\','\\'))`"} WHERE AssocClass = Win32_DiskDriveToDiskPartition"} | %{gwmi -Query "ASSOCIATORS OF {Win32_DiskPartition.DeviceID=`"$($_.DeviceID)`"} WHERE AssocClass = Win32_LogicalDiskToPartition"} | %{$_. deviceid} 

$drive = gwmi win32_volume | ? {$letters -contains ($_.name -replace "\\")} 

然后你就可以更改与以下驱动器号(必须是管理员)

$drive.DriveLetter = "O:" 
$drive.Put() 

编辑

确定这里是另一个尝试。下面的代码(我在这里找到:http://blogs.technet.com/b/heyscriptingguy/archive/2010/04/13/hey-scripting-guy-april-13-2010.aspx)允许创建一个WMI事件,该事件将在USB驱动器插入时触发。

我已经为该事件添加了一个操作,以便执行脚本块。 脚本块会检查USB驱动器的字母,如果不是,比如说“O:”,它会设置它。

我没有使用Wait-Job,因为只要事件存在,作业就会继续运行,并且我希望看到一些用于测试的输出。

在anycase,这应该是更接近你想要做什么:

$scriptblock = { 

    $driveLetter = "O:" 
    $diskdrive = gwmi win32_diskdrive | ?{$_.interfacetype -eq "USB"} 
    $letters = $diskdrive | %{gwmi -Query "ASSOCIATORS OF {Win32_DiskDrive.DeviceID=`"$($_.DeviceID.replace('\','\\'))`"} WHERE AssocClass = Win32_DiskDriveToDiskPartition"} | %{gwmi -Query "ASSOCIATORS OF {Win32_DiskPartition.DeviceID=`"$($_.DeviceID)`"} WHERE AssocClass = Win32_LogicalDiskToPartition"} | %{$_. deviceid} 

    $drive = gwmi win32_volume | ? {$letters -contains ($_.name -replace "\\")} 

    if ($drive.DriveLetter -ne $driveLetter) 
    { 
     $drive.DriveLetter = $driveLetter 
     $drive.Put() 
    } 
    $drive.DriveLetter 
} 

$job = Register-WmiEvent -Query "Select * from __InstanceCreationEvent within 5 where targetinstance isa 'win32_logicaldisk'" -SourceIdentifier usb -Timeout 1000 -Action $scriptblock 

while ($job.State -ne 'Stopped') 
{ 
    $job | Receive-Job 
    sleep 5 
} 
Unregister-Event -SourceIdentifier usb -Force | Out-Null 
$job | Remove-Job -force 

值得注意: 脚本块将收到的$ args以及$事件。我没有使用它们,但他们可能会进一步优化脚本。

+0

首先感谢你的答案之一,而这无疑将实现我的想法,我希望能找到一个更好的(或基本都ELE帮助gant)的方式来触发脚本或者只是绕过每次将驱动器连接在一起时运行某些东西 – Paul 2014-11-21 20:48:39

+0

在答案中更新,可能不是100%,但它是一些值得采纳的想法。 – 2014-11-22 11:07:04

+0

结合使用永久wmi事件是神话般的:)非常感谢你花时间帮助我!我将在星期一开始,并在我完成时将最终代码添加到线程 – Paul 2014-11-22 12:42:25

这里是我的代码可能会最终使用:

创建一个运行一个脚本永久WMI消费者:

$computer = "xxx" 
$filterNS = "root\cimv2" 
$wmiNS = "root\subscription" 
$query = "Select * from __InstanceCreationEvent within 5 where targetinstance isa 'win32_logicaldisk'" 

$filterName = "TestFilter" 

$filterPath = Set-WmiInstance -Class __EventFilter ` 
-ComputerName $computer -Namespace $wmiNS -Arguments ` 
    @{name=$filterName; EventNameSpace=$filterNS; QueryLanguage="WQL"; 
    Query=$query} 

$consumerPath = Set-WmiInstance -Class CommandLineEventConsumer ` 
-ComputerName $computer -Namespace $wmiNS ` 
-Arguments @{ 
name="TestConsumer"; 
ExecutablePath= "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"; 
CommandLineTemplate = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -executionpolicy bypass -file D:\\reassignDriveletter.ps1" 
} 

Set-WmiInstance -Class __FilterToConsumerBinding -ComputerName $computer ` 
    -Namespace $wmiNS -arguments @{Filter=$filterPath; Consumer=$consumerPath} | 
    out-null 

,这里是改变,如果器的序列号的驱动器号的脚本驱动相匹配的Backupdrives

$driveLetter = "Z:" 

$diskdrive = gwmi win32_diskdrive | ?{($_.interfacetype -eq "USB") -and $_.serialnumber.trim() -eq "761203FA9J813S" -or $_.serialnumber.trim() -eq "761239FA9J813S"} 
$letters = $diskdrive | %{gwmi -Query "ASSOCIATORS OF {Win32_DiskDrive.DeviceID=`"$($_.DeviceID.replace('\','\\'))`"} WHERE AssocClass = Win32_DiskDriveToDiskPartition"} | %{gwmi -Query "ASSOCIATORS OF {Win32_DiskPartition.DeviceID=`"$($_.DeviceID)`"} WHERE AssocClass = Win32_LogicalDiskToPartition"} | %{$_. deviceid} 
$drive = gwmi win32_volume | ? {$letters -contains ($_.name -replace "\\")} 

if ($drive.DriveLetter -ne $driveLetter) 
    { 
     $drive.DriveLetter = $driveLetter 
     $drive.Put() 
    }