PowerShell / PowerShell

PowerShell for every system!
https://microsoft.com/PowerShell
MIT License
43.66k stars 7.08k forks source link

PowerShell Jobs hang when using PSDrives with credentials #2884

Open dijitali opened 7 years ago

dijitali commented 7 years ago

When running a PowerShell Job which creates a PSDrive to a remote server using credentials, the job can "hang" in the Running state even when all actions have been completed. This is apparently caused by the way the PSCredential object is passed to the job, as illustrated in the script example below.

If the PSCredential object is created within the job, it will hang. However, if the PSCredential object (created in exactly the same way) is passed as a parameter, the job will finish normally.

Steps to reproduce

C:\scripts\MySimpleJob.ps1

Param(
    [string] $computer,
    [pscredential] $DeploymentCredential
)

if($DeploymentCredential -eq $null)
{
    $securePass = Get-Content "C:\scripts\passwords\dijitali.txt" | ConvertTo-SecureString
    $DeploymentCredential = New-Object PsCredential 'foobar\dijitali', $SecurePass
}

New-PSDrive -Name TargetServer -PSProvider FileSystem -Root ('\\' + $computer + '\c$') -Credential $deploymentCredential | Out-Null

$testinglog = 'TargetServer:\temp\TEST.txt'
if(Test-Path -Path $testinglog)
{
    Remove-Item -Path $testinglog -Force
}

New-Item $testinglog -ItemType 'File' -Force
((Get-Date -Format "yyyy-MM-dd\THH\:mm:ss:fff: ") + 'I can write to this file!') | Out-File -FilePath $testinglog

Launch the above script as a job without passing the $DeploymentCredential parameter and observer it takes roughly 180 seconds to complete:

$job = Start-Job -ScriptBlock {
                        C:\scripts\MySimpleJob.ps1 -Computer $args[0]
                       }`
          -ArgumentList @( 'MYTESTSERVER')
Wait-Job -Job $job
($job.PSEndTime - $job.PSBeginTime).TotalSeconds
# 184.0685204

Whereas if credentials are passed as a parameter, the job completes in a couple of seconds:

$SecurePass = Get-Content "C:\scripts\passwords\dijitali.txt" | ConvertTo-SecureString
$DeploymentCredential = New-Object PsCredential 'foobar\dijitali', $SecurePass

$job = Start-Job -ScriptBlock {
                        C:\scripts\MySimpleJob.ps1 -Computer $args[0] -deploymentCredential $args[1]
                       }`
          -ArgumentList @( 'MYTESTSERVER' , $DeploymentCredential)
Wait-Job -Job $job
($job.PSEndTime - $job.PSBeginTime).TotalSeconds
# 5.545685

Expected behavior

Jobs execute and change to Completed status within a few seconds.

Actual behavior

In PowerShell 4.0 the jobs appear to stay in the Running state indefinitely. In PowerShell 5.1 and 6.0.0-alpha the jobs stay in the Running state for ~180 seconds and then change to Completed.

Environment data

I have tested this on OS versions Server 2008 R2 (PowerShell 4.0 and 5.1) and Server 2012 R2 (PowerShell 5.1 and 6.0.0-alpha). Behaviour appears to be the same regardless of OS (on both executing server and remote server that is used as a PSDrive).

Name                           Value
----                           -----
PSVersion                      6.0.0-alpha
WSManStackVersion              3.0
BuildVersion                   3.0.0.0
SerializationVersion           1.1.0.1
CLRVersion
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
GitCommitId                    v6.0.0-alpha.13
PSEdition                      Core
dijitali commented 6 months ago

I'll try to reproduce this scenario but it may be a little while before I'm able to. It has been sometime since I raised this issue and I don't have the same environment available to me.

dijitali commented 2 weeks ago

Should be able to find some time to re-test in the next couple of weeks.