完成后自动删除PowerShell作业(异步)
我有一个PowerShell cmdlet,用于简化使用RDP连接到另一台计算机的过程 在该cmdlet中,我运行以下操作:完成后自动删除PowerShell作业(异步),powershell,jobs,cmdlet,Powershell,Jobs,Cmdlet,我有一个PowerShell cmdlet,用于简化使用RDP连接到另一台计算机的过程 在该cmdlet中,我运行以下操作: if ($null -ne $Username -and $null -ne $Password) { Start-Process -FilePath "cmdkey.exe" -ArgumentList @("/generic:`"TERMSRV/$ComputerName`"", "/user:`"$Username`"", "/pass:`"
if ($null -ne $Username -and $null -ne $Password) {
Start-Process -FilePath "cmdkey.exe" -ArgumentList @("/generic:`"TERMSRV/$ComputerName`"", "/user:`"$Username`"", "/pass:`"$Password`"") -WindowStyle Hidden
}
Start-Job -ScriptBlock {
param($InstallPath, $ComputerName, $Port, $Username, $Password)
$arguments = @("`"$(Join-Path $InstallPath '\Support Files\MSTSC\Default.rdp')`"")
if ($null -ne $Port) {
$arguments += "/v:`"$($ComputerName):$($Port)`""
} else {
$arguments += "/v:`"$($ComputerName)`""
}
Start-Process -FilePath "mstsc.exe" -ArgumentList $arguments -Wait
if ($null -ne $Username -and $null -ne $Password) {
Start-Process -FilePath "cmdkey.exe" -ArgumentList @("/delete:`"TERMSRV/$ComputerName`"") -WindowStyle Hidden
}
} -ArgumentList @($InstallPath, $ComputerName, $Port, $Username, $Password)
如您所见,我添加了用于连接远程计算机的凭据,然后启动一个执行mstsc.exe的作业,等待它完成,然后删除凭据
问题是我必须等待mstsc关闭,然后才能删除凭据,否则,它们会在mstsc有机会建立连接之前被删除,我希望此cmdlet是自包含的-立即将控制权返回到用户命令提示符,以便我可以在使用RDP会话时运行其他命令,这意味着我不能等待作业完成,因为这意味着我无法等待,直到完成为止断开与远程会话的连接:
| Wait-Job | Remove-Job
我想做的是,一旦作业完成,就可以删除它,也许可以使用某种回调,这样我就不必在注销RDP会话后手动运行另一个命令来清理该作业,并且该作业不会保持在已完成状态(这是我目前正在做的,但显然这不是“清理”)
有关完整cmdlet的详细信息,请参见此处:
因此,注册一个scheduledjob,在5分钟内运行,它将删除已完成的作业。我很确定你可以做如下事情:
Register-ScheduledJob -ScriptBlock {param($computername); Wait-Job -Name $ComputerName|remove-job} -Trigger @{Frequency="Once";At=(get-date).AddMinutes(5).ToString("h:MM tt")} -argumentlist $computername
然后,在执行启动作业时,只需在命令末尾附加
-name$ComputerName
即可为连接命名。这样,在你启动它5分钟后,一个预定的任务就会启动,按名称查找并清除该作业。我知道这是一个非常古老的问题。。。您可以使用Register ObjectEvent
在作业之后进行清理。作业具有一个StateChanged
事件,该事件具有传递给它的EventSubscriber
参数,该参数包含事件和源作业的详细信息
$job = Start-Job { Start-Sleep -Seconds 2 }
Register-ObjectEvent -InputObject $job -EventName StateChanged -Action {
Unregister-Event $EventSubscriber.SourceIdentifier
Remove-Job $EventSubscriber.SourceIdentifier
Remove-Job -Id $EventSubscriber.SourceObject.Id
} | Out-Null
这里有一个例子。作业完成后,回调将同时删除自身和源作业
$job = Start-Job { Start-Sleep -Seconds 2 }
Register-ObjectEvent -InputObject $job -EventName StateChanged -Action {
Unregister-Event $EventSubscriber.SourceIdentifier
Remove-Job $EventSubscriber.SourceIdentifier
Remove-Job -Id $EventSubscriber.SourceObject.Id
} | Out-Null
很抱歉回复太慢,我尝试了,但是此作业位于Get job/Get EventSubscriber列表上,等待完成后清理,因此仍然存在相同的问题。我现在采用的方法是创建一个新的PowerShell主机(),在那里添加清理代码,并用BeginInvoke启动它。它并不完美,因为它使用了更多的资源,我目前不调用EndInvoke(否则它会等待它完成),但希望使用InvocationStateChanged事件修复它。