Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
完成后自动删除PowerShell作业(异步)_Powershell_Jobs_Cmdlet - Fatal编程技术网

完成后自动删除PowerShell作业(异步)

完成后自动删除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:`"

我有一个PowerShell cmdlet,用于简化使用RDP连接到另一台计算机的过程

在该cmdlet中,我运行以下操作:

    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事件修复它。