Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Tuesday, March 6, 2012 7:54 AM
Hello,
If I use impersonation in PowerShell, remoting seems to fail. Not just fail, it actually crashes. The following script is an illustration of the problem.
It contains of 3 blocks:
- Try to do remoting => works
- Try to do remoting while being impersonated => fails
- Try to do remoting while being back under the original identity => works.
The error I am getting is inside PowerShell. I managed to trace it back to some unmanaged API calls, but now I'm stuck. Any ideas?
Or am I doing the impersonation incorrect?
$cred = Get-Credential 'DOM1\USER1'$cn = 'S000010'$port = 80# Without impersonation# =====================try{ $result = Invoke-Command -ComputerName $cn -Port $port -Credential $cred { 1 } if ($result -ne 1) { Write-Host 'Remoting seems to work, but the result is unexpected.' } else { Write-Host 'Remoting works as expected.' }}catch{ Write-Error 'FAILURE' Write-Error $_}# With impersonation# ==================$ImpersonationLib = Add-Type -Namespace 'Lib.Impersonation' -Name ImpersonationLib -MemberDefinition @" [DllImport("advapi32.dll", SetLastError = true)] public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); [DllImport("advapi32.dll", SetLastError = true)] public static extern bool DuplicateToken(IntPtr token, int impersonationLevel, ref IntPtr duplication); [DllImport("kernel32.dll")] public static extern Boolean CloseHandle(IntPtr hObject);"@ -PassThru[System.IntPtr]$userToken = [System.IntPtr]::Zero$success = $ImpersonationLib::LogonUser('USER1', # UserName 'DOM1', # Domain 'SECRETPASS', #Password 2, # LOGON32_LOGON_INTERACTIVE 0, # LOGON32_PROVIDER_DEFAULT [ref]$userToken) if ($success -eq $false){ Write-Host 'Failure to execute logon user.' Exit}# Create an identity.$Identity = New-Object Security.Principal.WindowsIdentity $userToken# Close open handles.if ($userToken -ne [System.IntPtr]::Zero){ $null = $ImpersonationLib::CloseHandle($userToken) $userToken = [System.IntPtr]::Zero}# Current user.Write-Host "Before impersonation: UserName: $([Security.Principal.WindowsIdentity]::GetCurrent().Name)"# Do the impersonation.$context = $Identity.Impersonate()# New user.Write-Host "After impersonation: UserName: $([Security.Principal.WindowsIdentity]::GetCurrent().Name)"try{ $result = Invoke-Command -ComputerName $cn -Port $port -Credential $cred { 1 } if ($result -ne 1) { Write-Host 'Remoting seems to work, but the result is unexpected.' } else { Write-Host 'Remoting works as expected.' }}catch{ Write-Error 'FAILURE' Write-Error $_}# Return to original user.$context.Undo()$context.Dispose()# Old user.Write-Host "After undoing impersonation: UserName: $([Security.Principal.WindowsIdentity]::GetCurrent().Name)"# Once more without impersonation# ===============================try{ $result = Invoke-Command -ComputerName $cn -Port $port -Credential $cred { 1 } if ($result -ne 1) { Write-Host 'Remoting seems to work, but the result is unexpected.' } else { Write-Host 'Remoting works as expected.' }}catch{ Write-Error 'FAILURE' Write-Error $_}
The actual error I'm getting when the code fails is:
C:\WINDOWS\TEMP\70bacc02-7fab-4130-a240-a4047460467c.ps1 : System.Management.Automation.PSInvalidOperationException at System.Management.Automation.Remoting.Client.WSManClientSessionTransportManager.Initialize(Uri connectionUri, WSManConnectionInfo connectionInfo) at System.Management.Automation.Remoting.Client.WSManClientSessionTransportManager..ctor(Guid runspacePoolInstanceId, WSManConnectionInfo connectionInfo, PSRemotingCryptoHelper cryptoHelper) at System.Management.Automation.Remoting.ClientRemoteSessionDSHandlerImpl..ctor(ClientRemoteSession session, PSRemotingCryptoHelper cryptoHelper, RunspaceConnectionInfo connectionInfo, URIDirectionReported uriRedirectionHandler) at System.Management.Automation.Remoting.ClientRemoteSessionImpl..ctor(RemoteRunspacePoolInternal rsPool, URIDirectionReported uriRedirectionHandler) at System.Management.Automation.Internal.ClientRunspacePoolDataStructureHandler.CreateClientRemoteSession(RemoteRunspacePoolInternal rsPoolInternal) at System.Management.Automation.Internal.ClientRunspacePoolDataStructureHandler..ctor(RemoteRunspacePoolInternal clientRunspacePool, TypeTable typeTable) at System.Management.Automation.Runspaces.Internal.RemoteRunspacePoolInternal..ctor(Int32 minRunspaces, Int32 maxRunspaces, TypeTable typeTable, PSHost host, PSPrimitiveDictionary applicationArguments, RunspaceConnectionInfo connectionInfo) at System.Management.Automation.Runspaces.RunspacePool..ctor(Int32 minRunspaces, Int32 maxRunspaces, TypeTable typeTable, PSHost host, PSPrimitiveDictionary applicationArguments, RunspaceConnectionInfo connectionInfo) at System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspacePool(Int32 minRunspaces, Int32 maxRunspaces, RunspaceConnectionInfo connectionInfo, PSHost host, TypeTable typeTable, PSPrimitiveDictionary applicationArguments) at System.Management.Automation.RemoteRunspace..ctor(TypeTable typeTable, RunspaceConnectionInfo connectionInfo, PSHost host, PSPrimitiveDictionary applicationArguments) at System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace(RunspaceConnectionInfo connectionInfo, PSHost host, TypeTable typeTable, PSPrimitiveDictionary applicationArguments) at Microsoft.PowerShell.Commands.PSExecutionCmdlet.CreateHelpersForSpecifiedComputerNames() at Microsoft.PowerShell.Commands.PSExecutionCmdlet.BeginProcessing() at Microsoft.PowerShell.Commands.InvokeCommandCommand.BeginProcessing() at System.Management.Automation.Cmdlet.DoBeginProcessing() at System.Management.Automation.CommandProcessorBase.DoBegin()At line:1 char:2+ . <<<< 'C:\WINDOWS\TEMP\70bacc02-7fab-4130-a240-a4047460467c.ps1' + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorExcep tion + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExceptio n,70bacc02-7fab-4130-a240-a4047460467c.ps1
All replies (2)
Wednesday, March 7, 2012 7:38 AM
Hi,
I have searched the internet and the below links should be helpful:
Best Regards,
Yan Li
Yan Li
TechNet Community Support
Wednesday, March 7, 2012 8:42 AM
The difference between that code and mine is that LogonUser is called with
LOGON32_LOGON_NEW_CREDENTIALS (9)
instead of
LOGON32_LOGON_INTERACTIVE (2)
I actually expect that once I do an impersonate as the new user, I could call invoke-command without having to provide the credentials parameter.
So I expect this to work:
$context = $Identity.Impersonate()$result = Invoke-Command -ComputerName $cn -Port $port { 1 }
This won't work if you specify LOGON32_LOGON_NEW_CREDENTIALS (9) in the call to LogonUser as it will just clone your current token and the invoke-command will connect you as the user which originally started the PowerShell session (the current one), and not the impersonated user. Although one would expect that it is an outbound connection and the specified credentials of the LogonUser would be used.