我使用以下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秒钟,以便为安装F提供truecrypt时间,然后运行在F上找到的脚本。似乎只有在连接/断开物理驱动器时才会生成卷更改事件(至少这是脚本收到事件的唯一时间),因为保持G连接并安装/卸载F不会触发脚本。
我希望能够检测到何时挂载truecrypt容器而没有任何其他更改。在某种程度上,这必须是可能的,因为Windows资源管理器在安装或卸载容器时更新其驱动器显示。我读了win32_VolumeChangeEvent
,但我无法找到与虚拟驱动器相关的任何内容。谢谢你的帮助。
答案 0 :(得分:1)
我很惊讶这已经持续了一年而且没有答案!对于任何访问过的人:
Register_WMIEvent 根本不适合我。相反,我采取了不同的方法来监控驱动器事件。不幸的是,脚本不是万无一失的,因为它在添加任何新驱动器时执行操作。随意添加更多条件。 我怀疑 win32_VolumeChangeEvent 的 Register_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对象的知识)。
答案 1 :(得分:0)
脚本posted by Koliat是一个非常好的脚本,它正在工作,但有两个错误,我已经修复了。 新的bugfree(我希望)脚本应该是这样的:
$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
}
}