2014-11-21 64 views
0

你好老鄉Stackoverflowers :)分配固定驅動器號在Windows Server上的USB設備(2012)

我尋找各種方法來分配驅動器號固定到USB驅動器的Windows Server 2012(基礎)上。

方案: 我的一個較小的客戶有2個USB驅動器用於他的服務器備份,每天都有一個交換機進行異地備份。目前,如果存在不匹配情況,他們將手動重新分配Drivelet。

我已經有了一個計劃來實現它,但想在實施它之前徵求建議,因爲我不確定這是最好的解決方案。

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

  1. 啓用DriverFramework-用戶模式日誌如果未啓用
  2. 創建由事件ID 2106
  3. 運行PowerShell腳本觸發計劃任務(通過如果設備ID相匹配的備份驅動器

之一分配驅動器號的計劃任務),所以現在的問題是:

以某種方式可以將固定驅動器號分配給一組USB設備,而無需在每次連接設備時都運行腳本?

如果沒有,是否有更好的方法來檢測設備何時連接並觸發任務?

當然,我做了一些研究,但只找到Windows7或Server2008的解決方案。我寧願在沒有第三方工具的情況下解決此問題。

預先感謝您對您能在這個話題給任何見解

問候保羅

回答

2

我不知道如果這能幫助很多,但我發現了一個不錯的職位在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

0

這裏是我的代碼可能會最終使用:

創建一個運行一個腳本永久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() 
    }