PowerShell Double Hop Issue - powershell

I’m trying to run a PowerShell script on SYSTEM1, which executes robocopy on SYSTEM2, copying files to SYSTEM3,4,5,etc.
SYSTEM1 and SYSTEM2 are on the same domain, but SYSTEM2 is not behind a firewall (hence the need to run robocopy from SYSTEM2 and not SYSTEM1).
SYSTEM3,4,5 are on different domains than SYSTEM2, as well as different domains than each other.
I set the script up like this (it uses the net use command to prompt the user for credentials for the different domains):
Foreach($server in $servers) {
$command = {
param($cred, $server);
$error.clear();
# Stored credentials in local variables
$user = $cred.GetNetworkCredential().username
$pass = $cred.GetNetworkCredential().password
#establish connection from SYSTEM2-> $server
net use \\$server\c$\Deployments /delete
net use \\$server\c$\Deployments /USER:$user $pass
# Check to see if C:\Deployments exists on server, and if not create it.
if ((Test-Path \\$server\c$\Deployments) -eq $FALSE) {
$c = {
New-Item \\$server\c$\Deployments -type directory
}
$ws = Invoke-Command -ComputerName $server -Credential $cred -ScriptBlock $c
}
# Copy over the deployment packages
$dest = "\\$server\Deployments\$DeploymentDate\$CurrentDirectoryName"
robocopy $CurrentDirectoryPath $dest /W:20 /R:15 /e /XF CopyPackage.ps1
# Delete connection from SYSTEM2 -> $server
net use \\$server\c$\Deployments /delete
However, the net use command returns an error after the credentials are entered:
The network connection could not be found.
+ CategoryInfo : NotSpecified: (The network con...d not be found.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
+ PSComputerName : SYSTEM2
More help is available by typing NET HELPMSG 2250.
System error 55 has occurred.
+ CategoryInfo : NotSpecified: (System error 55 has occurred.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
+ PSComputerName : SYSTEM2
The specified network resource or device is no longer available.
[SYSTEM3] Connecting to remote server failed with the following error message : WinRM cannot process the request. The
following error occured while using Kerberos authentication: There are currently no logon servers available to service
the logon request.
Possible causes are:
-The user name or password specified are invalid.
-Kerberos is used when no authentication method and no user name are specified.
-Kerberos accepts domain user names, but not local user names.
-The Service Principal Name (SPN) for the remote computer name and port does not exist.
-The client and remote computers are in different domains and there is no trust between the two domains.
After checking for the above issues, try the following:
-Check the Event Viewer for events related to authentication.
-Change the authentication method; add the destination computer to the WinRM TrustedHosts configuration setting or
use HTTPS transport.
Note that computers in the TrustedHosts list might not be authenticated.
-For more information about WinRM configuration, run the following command: winrm help config. For more
information, see the about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (:) [], PSRemotingTransportException
+ FullyQualifiedErrorId : PSSessionStateBroken
+ PSComputerName : SYSTEM2
The network connection could not be found.
+ CategoryInfo : NotSpecified: (The network con...d not be found.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
+ PSComputerName : SYSTEM2
More help is available by typing NET HELPMSG 2250.
I’ve read this could be a “double-hop” issue (as detailed here), but I’m not sure how to edit the script to use CredSSP instead of Kerberos (or if this is even the problem).
Any ideas?

Posting this solution in case someone is still having an issue with a simple resolution to DoubleHop without using CredSSP.
Try this out:
https://www.powershellgallery.com/packages/Invoke-PSSession
It Invokes a PSSession, then Registers a PSSessionConfiguration with the Credentials that you provided. Basically providing the credentials for that DoubleHop
Then use Invoke-Command with that new PSSession. It should have the required privileges to do what you need.

Related

PowerShell 5.1 What is wrong with my New-PSSession syntax

Environment:
PowerShell 5.1
Windows 2016 Standard
Windows 10 Pro
Just asking here if syntax is fundamentally correct...
$hostSession = New-PSSession -ComputerName $hostName -Credential $cred
$versionFolder = "c:\temp"
$sspLatestVer = Invoke-Command -Session $hostSession -ScriptBlock { param($path) (Get-ChildItem $path | Sort-Object LastWriteTime -Descending | Select-Object -First 1).Name } -ArgumentList $versionFolder
Update:
The following works on one machine but not on another:
$versionFolder = "\\COMPUTER01\c$\temp"
$sspLatestVer = (Get-ChildItem $versionFolder | Sort-Object LastWriteTime -Descending | Select-Object -First 1).Name
Error Message for machine that doesn't work
Get-ChildItem : Cannot find path '\\COMPUTER01\c$\temp' because it does not exist.
At C:\temp\candidate2.ps1:24 char:18
+ $sspLatestVer = (Get-ChildItem $versionFolder | Sort-Object LastWrite ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (\\COMPUTER01\c$\temp:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
OP Error Message:
New-PSSession : [COMPUTER01] Connecting to remote server COMPUTER01 failed with the following error message : WinRM cannot process the request. The following error with errorcode 0x80090311 occurred while using
Kerberos authentication: We can't sign you in with this credential because your domain isn't available. Make sure your device is connected to your organization's network and try again. If you previously signed in on
this device with another credential, you can sign in with that credential.
Possible causes are:
-The user name or password specified are invalid.
-Kerberos is used when no authentication method and no user name are specified.
-Kerberos accepts domain user names, but not local user names.
-The Service Principal Name (SPN) for the remote computer name and port does not exist.
-The client and remote computers are in different domains and there is no trust between the two domains.
After checking for the above issues, try the following:
-Check the Event Viewer for events related to authentication.
-Change the authentication method; add the destination computer to the WinRM TrustedHosts configuration setting or use HTTPS transport.
Note that computers in the TrustedHosts list might not be authenticated.
-For more information about WinRM configuration, run the following command: winrm help config. For more information, see the about_Remote_Troubleshooting Help topic.
At C:\Users\RSTEST\Documents\candidate2.ps1:17 char:16
+ ... hostSession = New-PSSession -ComputerName $hostName -Credential $cred
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (System.Manageme....RemoteRunspace:RemoteRunspace) [New-PSSession], PSRemotingTransportException
+ FullyQualifiedErrorId : AuthenticationFailed,PSSessionOpenFailed
Invoke-Command : Cannot validate argument on parameter 'Session'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At C:\Users\RSTEST\Documents\candidate2.ps1:19 char:41
+ $sspLatestVer = Invoke-Command -Session $hostSession -ScriptBlock { p ...
+ ~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Invoke-Command], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.InvokeCommandCommand
Remove-PSSession : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At C:\Users\RSTEST\Documents\candidate2.ps1:20 char:24
+ Remove-PSSession -Name $hostSession
+ ~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
Two issues here:
First, see WinRM cannot process the request. Error 0x80090311
If the remote system is in the same domain, and you are already logged in with a domain account that is an administrator on that system, then there would be no need to specify a credential for New-PSSession
If the systems are in different forests that have a trust with each other, note that there is a need to use the fully qualified domain name (FQDN) of the remote host for Kerberos authentication to function correctly.
Second, regarding:
$versionFolder = "\\COMPUTER01\c$\temp"
Note that remote sessions normally do not have access to network shares, even when presumably running under the credentials of an administrative user.
This is known as the "second hop problem". There have been various posts about it:
https://learn.microsoft.com/en-us/powershell/scripting/learn/remoting/ps-remoting-second-hop?view=powershell-5.1
https://devblogs.microsoft.com/scripting/enable-powershell-second-hop-functionality-with-credssp/
This may work from COMPUTER01 itself, since it could be aliased to local drive access.

Access to password protected network share (double/second hop limitation)

This is about the famous double-hop limitation that looks trivial and has at least 10 workarounds but I cannot find even one that works for my setup.
Here is my environment: I have ~50 virtual machines on Windows 10, every VM runs on a separate hardware - we use virtual machines because our IT guys claim it's easier to maintain and physical ones, I personally dislike VMs but it's not something that depends on me.
We are on a non-domain environment, no Active Directory, we use a workgroup and every machine is administered individually.
My goal is to optimize PC management like installing software, registering/starting services and etc - I need to do that on all machines at once not to perform each task 50 times. I managed to run PowerShell remote relatively quickly but very soon I stuck on non being able to access any network resource that requires additional authentication (all our network shares requires LDAP authentication).
What I tried so far.
Re-authenticate from the session, described here:
$mappedDrive = #{
Name = "u"
PSProvider = "FileSystem"
Root = "\\bladefs\share2"
Credential = 'svetlozar.draganov'
}
Invoke-Command -ComputerName bw33 -ScriptBlock {
New-PSDrive #using:mappedDrive
Get-Content -Path \\bladefs\share2\text.txt
Get-PSDrive
Remove-PSDrive -Name "u"
Get-PSDrive
} -Credential render
What the above command does is to run a remote command via Invoke-Command that request two authentications, the first authentication is to connect to the machine bw33 then with a New-PSDrive command another authentication is sent to an already establishes session with bw33 to mount a network share with username and password. This sometimes on very rare occasions actually works, but I cannot pinpoint when and why it works and why in most of the cases doesn't work. Even though I'm executing absolutely the same PowerShell script a dozen of times it only works for a very small percentage of them the rest of them it just says this:
A specified logon session does not exist. It may already have been
terminated
+ CategoryInfo : InvalidOperation: (u:PSDriveInfo) [New-PSDrive], Win32Exception
+ FullyQualifiedErrorId : CouldNotMapNetworkDrive,Microsoft.PowerShell.Commands.NewPSDriveCommand
+ PSComputerName : bw33
Cannot find path '\\bladefs\share2\text.txt' because it does not exist.
+ CategoryInfo : ObjectNotFound: (\\bladefs\share2\text.txt:String) [Get-Content], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
+ PSComputerName : bw33
I actually captured a working and non-working attempt on the video bellow:
https://drive.google.com/uc?id=1HYD8p-VkLYyIExZVWO_8qgpI2kmlUDgF
As you can see with first execution everything is fine PSDrive is mapped successfully and I can reach \bladefs\share2 network path but with second execution I got some errors.
Similar as the above but instead of mapping drive via PSDrive command mapping it via NET USE command with username and password.
Invoke-Command -ComputerName bw33 -Credential render -ScriptBlock {
net use x: \\bladefs\share2 /user:svetlozar.draganov password
Test-Path \\bladefs\share2
}
This, as the first, sometimes works but again it only works once, all subsequent execution leads to this error:
System error 1312 has occurred.
+ CategoryInfo : NotSpecified: (System error 1312 has occurred.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
+ PSComputerName : bw33
A specified logon session does not exist. It may already have been terminated.
Here is a video of another attempt that again captures working and non-working execution of that command:
https://drive.google.com/uc?id=1wP20sbmXMfWu4dvjsdF8REDWgNxiKAS-
Using CredSSP described here:
$session = New-PSSession -cn bw33 -Credential render -Authentication Credssp
Invoke-Command -Session $session -ScriptBlock {Test-Path \\bladefs\share2}
Although this is the most popular and insecure way to resolve this issue I decided to give it a try cause recommended options didn't work. Unfortunately I hit a brick with this approach as well, here are the errors:
New-PSSession : [bw33] Connecting to remote server bw33 failed with
the following error message : The request is not supported. For more
information, see the about_Remote_Troubleshooting Help topic.
At line:1 char:12
+ $session = New-PSSession -cn bw33 -Credential render -Authentication ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (System.Manageme....RemoteRunspace:RemoteRunspace) [New-PSSession], PSRemotingTransportException
+ FullyQualifiedErrorId : 50,PSSessionOpenFailed
Invoke-Command : Cannot validate argument on parameter 'Session'. The
argument is null or empty. Provide an argument that is not null or empty,
and then try the command again.
At line:2 char:25
+ Invoke-Command -Session $session -ScriptBlock {Test-Path \\bladefs\sh ...
+ ~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Invoke-Command], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.InvokeCommandCommand
And respectively the video:
https://drive.google.com/uc?id=10tbAq6vvRsvT-1SGqOzvPgIPcM-MT8CJ
I had a somewhat similar issue to yours a while back, but I have a domain joined setup. That shouldn't make to much difference as long as you have the credentials. In your example you don't seem to be using an actual PSCredential object, which might be you issue. If you can use the same credential to connect to the remote system and then back to your share then this should work:
$Password = Read-Host -Prompt 'Enter Password' -AsSecureString
$Credential = New-Object -TypeName PSCredential('username',$Password)
$mappedDrive = #{
Name = "u"
PSProvider = "FileSystem"
Root = "\\bladefs\share2"
Credential = $Credential
}
Invoke-Command -ComputerName bw33 -Credential $Credential -ScriptBlock {
New-PSDrive #Using:mappedDrive
# Do Stuff...
Remove-PSDrive -Name "u"
}

Enter-PSSession not working, Firewall port 5985 is open

Error:
Enter-PSSession : Connecting to remote server sadcm0000081 failed with the following error message : WinRM cannot
complete the operation. Verify that the specified computer name is valid, that the computer is accessible over the
network, and that a firewall exception for the WinRM service is enabled and allows access from this computer. By
default, the WinRM firewall exception for public profiles limits access to remote computers within the same local
subnet. For more information, see the about_Remote_Troubleshooting Help topic.
At line:1 char:1
+ Enter-PSSession -ComputerName sadcm0000081
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (sadcm0000081:String) [Enter-PSSession], PSRemotingTransportException
+ FullyQualifiedErrorId : CreateRemoteRunspaceFailed
Test-WSN Output:
Test-Wsman : <f:WSManFault xmlns:f="http://schemas.microsoft.com/wbem/wsman/1/wsmanfault" Code="2150859046" Machine="SADCM0000078.adc
.corpintra.net"><f:Message>WinRM cannot complete the operation. Verify that the specified computer name is valid, that the computer i
s accessible over the network, and that a firewall exception for the WinRM service is enabled and allows access from this computer. B
y default, the WinRM firewall exception for public profiles limits access to remote computers within the same local subnet. </f:Messa
ge></f:WSManFault>
At line:1 char:1
+ Test-Wsman -ComputerName sadcm0000081
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (sadcm0000081:String) [Test-WSMan], InvalidOperationException
+ FullyQualifiedErrorId : WsManError,Microsoft.WSMan.Management.TestWSManCommand
Try first to running powershell Enable-PSRemoting with an administrator console.
After that look after the Windows Firewall rules of remote administration.

Why does Invoke-Command { net localgroup } fail?

I can successfully use NET USE and NET USER commands on the remote machine. Why not NET LOCALGROUP?
PS C:\src\powershell> Invoke-Command -ComputerName OTHERMACHINE -ScriptBlock { & NET LOCALGROUP }
System error 1312 has occurred.
+ CategoryInfo : NotSpecified: (System error 1312 has occurred.:String) [], Rem
oteException
+ FullyQualifiedErrorId : NativeCommandError
+ PSComputerName : OTHERMACHINE
A specified logon session does not exist. It may already have been terminated.
Passing the /USER parameter produces a different error.
PS C:\src\powershell> Invoke-Command -ComputerName OTHERMACHINE -ScriptBlock { & net localgroup /USER:THEDOM\theuser }
The option /USER:THEDOM\theuser is unknown.
+ CategoryInfo : NotSpecified: (The option /USE...son is unknown.:String) [], R
emoteException
+ FullyQualifiedErrorId : NativeCommandError
+ PSComputerName : OTHERMACHINE
The syntax of this command is:
NET LOCALGROUP
[groupname [/COMMENT:"text"]] [/DOMAIN]
groupname {/ADD [/COMMENT:"text"] | /DELETE} [/DOMAIN]
groupname name [...] {/ADD | /DELETE} [/DOMAIN]
More help is available by typing NET HELPMSG 3506.
I believe this is the double-hop problem. You get the same error if you try to execute net localgroup administrators in a session created with Enter-PSSession: "System error 1312 has occurred." and "A specified logon session does not exist. It may already have been terminated."
net.exe is trying to reauthenticate, but it can't reuse the credentials of the session. You may have success using CredSSP, which requires some setup and, IIRC, may have security implications. You'll have to enable CredSSP on the remote system and local system, and then delegate correctly. Even then I'm seeing conflicting reports about this working. There may even be security policies preventing it.
Personally, I just wouldn't use net.exe at all. That's too many hoops to jump through for something so basic. You can retrieve the members of a local group remotely via the ADSI provider, which is probably much easier and much more likely to work.

PS Remote session without passing credentials

I want to start a New-PSSession without having to pass credentials in a script. I know you can get the password from a file or have it hardcoded in the script and then convert it to a secure string to start the session. However, I want to start the session using the current user's credentials.
The machine I am trying to remote to is in the same domain.
I tried:
Enter-PSSession -ComputerName machineInDomain
Enter-PSSession : Connecting to remote server failed with the
following error message : WinRM cannot process the request. The
following error occured while using Kerberos authentication: The
network path was not found. Possible causes are:
-The user name or
password specified are invalid.
-Kerberos is used when no
authentication method and no user name are specified.
-Kerberos
accepts domain user names, but not local user names.
-The Service
Principal Name (SPN) for the remote computer name and port does not
exist. -The client and remote computers are in different domains and
there is no trust between the two domains. After checking for the
above issues, try the following:
-Check the Event Viewer for events
related to authentication.
-Change the authentication method; add
the destination computer to the WinRM TrustedHosts configuration
setting or us e HTTPS transport. Note that computers in the
TrustedHosts list might not be authenticated.
-For more information
about WinRM configuration, run the following command: winrm help
config. For more information, see the about_Remote_Troubleshooting
Help topic.
At line:1 char:16
+ Enter-PSSession <<<< -ComputerName machineInDomain
+ CategoryInfo : InvalidArgument: (machineInDomain:String) [Enter-PSSession],
PSRemotingTransportException
+ FullyQualifiedErrorId : CreateRemoteRunspaceFailed
Kerberos should pass the current user's credentials with trust if in the same domain.
Enter-PSSession -ComputerName $RemoteHost -Authentication Kerberos
Enter-PSSession : Connecting to remote server failed with the following error message
: WinRM cannot process the request. The following error occurred while using Kerberos authentication: The computer
$RemoteHost is unknown to Kerberos. Verify that the computer exists on the network, that the name
provided is spelled correctly, and that the Kerberos configuration for accessing the computer is correct. The most
common Kerberos configuration issue is that an SPN with the format HTTP/$RemoteHost is not
configured for the target. If Kerberos is not required, specify the Negotiate authentication mechanism and resubmit
the operation. For more information, see the about_Remote_Troubleshooting Help topic.
At line:1 char:1
+ Enter-PSSession -ComputerName $RemoteHost -Authentication Ke ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: ($RemoteHost) [Enter-PSSession], PSRemotingTransportException
+ FullyQualifiedErrorId : CreateRemoteRunspaceFailed
It seems to be a domain problem.