6

我正在使用以下 windows powershell 脚本来检测何时安装了特定卷,因此我可以运行一个脚本,将文件从我的机器移动到设备(我对 powershell 脚本了解不多,我在网上找到了这个)。

#Requires -version 2.0
Register-WmiEvent -Class win32_VolumeChangeEvent -SourceIdentifier volumeChange
write-host (get-date -format s) "     Beginning script..."
do{
  $newEvent = Wait-Event -SourceIdentifier volumeChange
  $eventType = $newEvent.SourceEventArgs.NewEvent.EventType
  $eventTypeName = switch($eventType)
    {
    1 {"Configuration changed"}
    2 {"Device arrival"}
    3 {"Device removal"}
    4 {"docking"}
    }
  write-host (get-date -format s) "     Event detected = " $eventTypeName
  if ($eventType -eq 2)
  {
    $driveLetter = $newEvent.SourceEventArgs.NewEvent.DriveName
    $driveLabel = ([wmi]"Win32_LogicalDisk='$driveLetter'").VolumeName
    write-host (get-date -format s) "     Drive name = " $driveLetter
    write-host (get-date -format s) "     Drive label = " $driveLabel
    # Execute process if drive matches specified condition(s)
    if ($driveLetter -eq 'G:' -and $driveLabel -eq 'My Book')
    {
        write-host (get-date -format s) "     Starting task in 5 seconds..."
     start-sleep -seconds 5
        start-process "F:\copy_backups.bat"
    }
  }
  Remove-Event -SourceIdentifier volumeChange
} while (1-eq1) #Loop until next event
Unregister-Event -SourceIdentifier volumeChange

G是物理外置硬盘,F是G内的truecrypt容器。当脚本检测到正确的设备被挂载为G时,它会休眠5秒给truecrypt时间来挂载F,然后运行在F上找到的脚本。出现卷更改事件仅在物理驱动器连接/断开连接时生成(至少这是脚本接收事件的唯一时间),因为保持 G 连接和挂载/卸载 F 不会触发脚本。

我希望能够检测何时安装了 truecrypt 容器,而无需进行任何其他更改。在某种程度上,这必须是可能的,因为 Windows 资源管理器会在安装或卸载容器时更新其驱动器显示。我阅读了win32_VolumeChangeEvent,但我找不到与虚拟驱动器相关的任何信息。谢谢您的帮助。

4

2 回答 2

1

我很惊讶这已经过去一年了,还没有答案!对于任何访问的人:

Register_WMIEvent根本不适合我。相反,我采用了不同的方法来监控驱动事件。不幸的是,该脚本并非万无一失,因为它会在添加任何新驱动器时执行操作。随意添加更多条件。我怀疑win32_VolumeChangeEventRegister_WMIEvent仅在更改物理驱动器时监视,根据卷管理器条目。

这是应该允许您执行任何您想要的操作的脚本。(提示:可能将您的 TC 容器挂载在高位,并将功能仅限于这些,以便在连接一些低位驱动器(例如 pendrive)时脚本不会触发)

$DrivesCount = (gwmi -Query "Select * from Win32_LogicalDisk").Count
$Drives = (gwmi -Query "Select * from Win32_LogicalDisk")

while(1) {
Start-Sleep -Seconds 5
    $DrivesCountNew = (gwmi -Query "Select * from Win32_LogicalDisk").Count
        if ($DrivesCount -ne $DrivesCountNew) 
          {
          $DrivesNew = (gwmi -Query "Select * from Win32_LogicalDisk")
          $DriveLetter = Compare-Object -ReferenceObject $Drives -DifferenceObject $DrivesNew | Select -ExpandProperty InputObject | Select -ExpandProperty DeviceId
          if (!($DriveLetter -eq $null)) { 
          Write-host "New drive mounted $DriveLetter"

          ##Place for you to do something with your drive
          }
          $DrivesCount = (gwmi -Query "Select * from Win32_LogicalDisk").Count 
          }
         }

至于围绕脚本的快速评论:

$DrivesCount获取驱动器列表的初始值并将$Drives它们全部列出到变量中。之后,无限循环开始,如果安装了新驱动器,它将每 5 秒计数一次 ( $DrivesCountNew)。如果未注册任何更改,则不采取任何措施(值相同)。但是,如果出现新驱动器,$DriveLetter变量会通过比较差异进行检查并返回驱动器的唯一字母(通过使用ExpandProperty几次.

之后,将进行检查,$DriveLetter因为如果驱动器被移除,脚本将触发(并且我们不希望在此位置发生任何操作)。当然脚本之后会执行任何脚本块,所以通过添加一些条件来限制执行是明智的(比如:)if ($DriveLetter -eq "Z:") { }然后,在成功执行结束时,它会$DrivesCount再次覆盖变量(以防止脚本重复作为旧变量的操作仍然有效)。

好吧,很抱歉您没有及时得到回复——但我希望有人会发现这个脚本很有用。(至少我学到了更多关于 WMI 对象的知识)。

于 2014-06-18T20:53:45.310 回答
0

Koliat 发布的脚本是一个非常好的脚本,它正在工作,但是其中有两个错误,我已经修复了。新的无错误(我希望)脚本应该如下所示:

$DrivesCount = (gwmi -Query "Select * from Win32_LogicalDisk").Count
$Drives = (gwmi -Query "Select * from Win32_LogicalDisk")

while(1) {
    Start-Sleep -Seconds 5
    $DrivesCountNew = (gwmi -Query "Select * from Win32_LogicalDisk").Count
    if ($DrivesCount -ne $DrivesCountNew) {
        $DrivesNew = (gwmi -Query "Select * from Win32_LogicalDisk")
        $DriveLetter = Compare-Object -ReferenceObject $Drives -DifferenceObject $DrivesNew | Select -ExpandProperty InputObject | Select -ExpandProperty DeviceId

        if (!($DriveLetter -eq $null)) { 

            $match = $DrivesNew -match $DriveLetter

            if ([string]::IsNullOrEmpty($match)) {
                write-host "Drive $DriveLetter REMOVED"
            } else {
                Write-host "Drive $DriveLetter MOUNTED"
                ##Place for you to do something with your drive
                if ($DriveLetter -eq "M:") {
                    write-host " Starting task in 3 seconds..."
                    start-sleep -seconds 3
                    #start-process "anything"
                }
            }    
        }
        $DrivesCount = $DrivesCountNew
        $Drives = $DrivesNew
    }
}
于 2017-04-14T09:59:36.737 回答