I have a PowerShell cmdlet which I use to simplify connecting to another computer with RDP.
Within that cmdlet I run do the following:
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)
As you can see I add the credentials used to connect to the remote machine, then start a job which executes mstsc.exe, waits for it to finish then removes the credentials.
The problem is I have to wait for mstsc to close before deleting the credentials, as otherwise they get removed before mstsc has a chance to establish the connection and I want this cmdlet to be self contained - returning control immediately to the users command prompt so I can run other commands while I am also using the RDP session which means I can't wait for the job to finish as that mean I am stuck waiting until I disconnect from the remote session:
| Wait-Job | Remove-Job
What I want to do is to be able to Remove-Job once it has completed, perhaps using some kind of callback so I don't have to manually run another command to clean up the Job once I log out of the RDP session and the Job isn't left in a Completed state (which is what I am currently doing but obviously this isn't 'clean).
For the full cmdlet you can see it here for more context:
https://github.com/paulmarsy/Console/blob/master/AdvancedPowerShellConsole/Exports/Functions/Connect-Remote.ps1
I know this is a very old question... You can use Register-ObjectEvent
to clean up after jobs. Jobs have a StateChanged
event that has an EventSubscriber
parameter passed to it containing details of the event and the source job.
Here's an example. Once the job completes the callback will remove both itself and the source job.
$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
So register a scheduledjob to run in 5 minutes that will remove the completed job. I am pretty sure that you can do something like:
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
Then just give your connection a name when you do your Start-Job by appending -Name $ComputerName
to the end of the command. That way 5 minutes after you launch it a scheduled task kicks off that finds and clears out that job by name.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With