WINRM credentials in remote script block not working as expected - powershell

I am trying to use WINRM to connect to one host (in the internal domain) and then from there WINRM into another server in another domain (the DMZ). Below is an example:
$domainServer = 'DOMAINSERVER'
$dmzServer = 'DMZSERVER'
$domainCred = Get-Credential -Message "Enter domain creds"
$dmzCred = Get-Credential -Message "Enter dmz creds"
Invoke-Command -ComputerName $domainServer -ArgumentList $dmzServer,$dmzCred -ScriptBlock {
Write-Host "connected to $domainServer"
Invoke-Command -ComputerName $args[0] -ScriptBlock {
Write-Host "connected to $args[0]"
} -Credential $args[1]
} -Credential $domainCred
However when I try this I am getting this error:
[DMZSERVER] Connecting to remote server DMZSERVER failed with the following error message : WinRM cannot process the request. The
following error with errorcode 0x80090311 occurred while using Kerberos authentication: There are currently no logon servers available to service the
logon request.
I am able to open a WINRM session from DOMAINSERVER to DMZSERVER if I log on to DOMAINSERVER and open a console and try there, so the problem is something with my nested "invoke-command"

Related

New-PSSession - WinRM cannot process the request

I am trying to list all the websites in IIS on a remote server using PowerShell scripting. Below is how I am trying to connect to the server:
$s = New-PSSession -ComputerName $Server
But when I run the script I am getting the following error:
New-PSSession : [Server] Connecting to remote server Server failed with the
following error message : WinRM cannot process the request. The following error
occurred while using Kerberos authentication: Cannot find the computer Server.
Verify that the computer exists on the network and that the name provided is
spelled correctly. For more information, see the about_Remote_Troubleshooting
Help topic.
At C:\AppServers\Application.ps1:8 char:8
+ $s = New-PSSession -ComputerName Server
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (System.Manageme....RemoteRunspace:RemoteRunspace) [New-PSSession], PSRemotingTransportException
+ FullyQualifiedErrorId : NetworkPathNotFound,PSSessionOpenFailed
The server is already enabled to receive remote requests.
Update:
Below is the full function that i am trying to run:
function audit-servers {
if (Test-path "ApplicationsOnTheServer.txt") {Remove-Item "ApplicationsOnTheServer.txt"}
if (Test-Path "ServersList.txt") {
foreach ($server in Get-Content .\ServersList.txt) {
"Application Server : $server`n" | out-file -FilePath "ApplicationsOnTheServer.txt" -Append
"Applications list:" | out-file -FilePath "ApplicationsOnTheServer.txt" -Append
$s = New-PSSession -ComputerName $server -Credential domainabc\myname
Invoke-Command -Session $s -ScriptBlock {Import-Module WebAdministration;Get-iissite} | out-file -FilePath "ApplicationsOnTheServer.txt" -Append
}
} else {
"ServersList.txt file is missing"
break;
}
"`nAll Done!`n"}
The ServersList.txt has atstappvmabc.tsteag.com
The error message clearly states that you wanted to connect to the server named Server not to the server which name is stored in $Server variable (text in bold is actually the name of the server you try to connect to):
New-PSSession : [Server] Connecting to remote server Server failed
If you tried to connect to the server named for example MyServer01.example.com you'd receive the error like below (truncated):
PS C:\> New-PSSession -ComputerName "MyServer01.example.com"
New-PSSession : [MyServer01.example.com] Connecting to remote server MyServer01.example.com failed (...)
Even though you state that you try to execute
$s = New-PSSession -ComputerName $Server
You actually execute (notice missing dollar sign)
$s = New-PSSession -ComputerName Server
The above was also taken from the error message you pasted. I'd suggest to first skip the variable and try to enter server path in the command itself to verify it's working:
$s = New-PSSession -ComputerName "MyServer01.example.com"
And then, if it works, put the path in variable and test again.
The error you're receiving FullyQualifiedErrorId : NetworkPathNotFound generally means that the name you're passing to the -ComputerName parameter can't be resolved.
Perhaps try running Test-Connection $Server to troubleshoot what's happening there.
Your variable $Server contains wrong value. You have to assign valid computer name to $Server.

Couldn't use Get-WinEvent from remote computer in VLAN

The remote computer are Win-10 VM in a VLAN.
We only have a few ports open in VLAN, including 3389 for Remote Desktop, 5985 & 5986 for powershell.
Remote Desktop works well.
But I couldn't to use powershell to remote debug on those computers,
If I run
Get-WinEvent -LogName System -Credential domain\test_user -ComputerName 10.100.155.1
I get this error
Get-WinEvent : The RPC server is unavailable
If I use invoke-command to execute the same script,
Invoke-Command -ComputerName 10.100.155.1 -Credential domain\test_user -ScriptBlock {Get-WinEvent -LogName System -Credential domain\test_user -ComputerName 10.100.155.1}
I will get another error:
[10.100.155.1] Connecting to remote server 10.100.155.1 failed with the following error message : Access is denied.
I have tried many solutions on internet, unfortunately, none is working. For example, I have checked if the services are running, if the firewall allows remote event management on remote computer, they looks alright.
Any idea where could be wrong?
Your problem is two-fold.
You cannot use WinRM (Invoke-Command) with an IP address. It uses Kerberos and Kerberos requires a DNS name.
You're passing your credentials and computername twice.
This should work without a problem:
$InvokeArgs = #{
ComputerName = 'Computername.domain.com'
Credential = (Get-Credential -Credential domain\test_user)
ScriptBlock = { Get-WinEvent -LogName System }
}
Invoke-Command #InvokeArgs
Access Denied is an Authentication Issue, double check your username and password.
I was working on a similar problem, trying to fetch count of system logons. Here's what worked for me:
$fetchEvents = { Get-WinEvent -FilterHashtable #{
Logname='system'
ProviderName='Microsoft-Windows-Winlogon'
StartTime=(get-date).AddDays(-10)
ID = 7001
} | Format-Table -Property TimeCreated, UserID, ID, MachineName }
Invoke-Command -ComputerName $ServerList -Credential $creds -ScriptBlock $fetchEvents

Using Powershell to remotely invoke commands in Azure

I'm writing a series of automation scripts that will allow our developers to stand up a simple development environment in Azure. This environment has 3 primary properties:
There is a client machine (Windows 10) where dev tools like their IDE and code will live.
There is a server machine (Windows Server 2016) where that their scripts will target.
Both of these machines live in the same domain, and 1 Domain Admin user is available for use.
I have steps 1 and 2 scripted out, but 3 is currently a mess. Since the script is designed to work from the Developer's local workstation, I need to have the script remote in to the Windows Server and run a few commands to set up the Domain Controller.
Here is my code currently:
Invoke-Command -ComputerName "$RGName-$VMPurpose" -ScriptBlock
{
$ADFeature = Install-WindowsFeature AD-Domain-Services
If ($ADFeature.Success -eq $true)
{
Import-Module ADDSDeployment
Install-ADDSForest -CreateDnsDelegation:$false -DatabasePath
"C:\Windows\NTDS" -DomainMode "Win2016R2" -DomainName "$project.com" -
DomainNetbiosName "$project" -ForestMode "Win2016R2" -InstallDns:$true -
LogPath "C:\Windows\NTDS" -NoRebootOnCompletion $false -sysvolpath
"C:\Windows\SYSVOL" -force $true
$domUserPassword = ConvertTo-SecureString "Th1s is a bad password" -
AsPlainText -Force
New-ADUser -Name "$VMPurpose-DomAdm" -AccountPassword
$domUserPassword
Add-ADGroupMember -Name "Administrators" -Member {Get-ADUser
"$VMPurpose-DomAdm"}
}
} -Credential $Cred
When I attempt to run this I get an error showing that WinRM cannot connect, specifically this error:
[Foo] Connecting to remote server Foo failed with the following error
message : WinRM cannot process the request. The following error with
errorcode 0x80090311
occurred 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: (Foo:String) [],
PSRemotingTransportException
+ FullyQualifiedErrorId : AuthenticationFailed,PSSessionStateBroken
I added the target machine (Foo) to the TrustedHosts configuration setting in WinRM (I actually added the IP address to make sure that there wasn't any DNS problem happening), and then I get this error:
[Foo's IP] Connecting to remote server <Foo's IP> 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.
+ CategoryInfo : OpenError: (Foo's Ip[:String) [],
PSRemotingTransportException
+ FullyQualifiedErrorId : WinRMOperationTimeout,PSSessionStateBroken
Any thoughts here? Am what I trying simply not ever going to work via Powershell?
According to your error message, we can use this PowerShell script to invoke command to Azure:
$username = 'jason'
$pass = ConvertTo-SecureString -string 'password' -AsPlainText -Force
$cred = New-Object -typename System.Management.Automation.PSCredential -argumentlist $username, $pass
$s = New-PSSession -ConnectionUri 'http://23.99.82.2:5985' -Credential $cred -SessionOption (New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck)
Invoke-Command -Session $s -ScriptBlock {Get-Process PowerShell}
PowerShell result like this:
More information about invoke command, please refer to this answer.

WinRM cannot process the request

"Connecting to remote server failed with the following error message : WinRM cannot process the request. The following error with errorcode 0x80090304 occurred while using Negotiate authentication: An unknown security error occurred."
I'm attempting to run scripts remotely to non-domain servers and the clients are also not part of a domain since our environment is based on MicroFocus eDirectory.
I've configured/tried the following on both client AND server:
winrm quickconfig
WinRM set winrm/config/client #{TrustedHosts="*"}
Set-item wsman:localhost\client\trustedhosts -value *
And again, none of the machines are part of a domain but I assumed it would work with trustedhosts.
Code attempting to authenticate looks like this:
[xml]$windows=(Get-Content P:\script\windows.xml)
$windows.servers.host | ForEach-Object {
$password = ConvertTo-SecureString $_.pass -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "$_.name+$_.user",$password
Invoke-Command -ComputerName $_.name -Credential $credential -ScriptBlock {Get-Culture}
}
Your problem is in the formatting of the username. "$.name+$.user" will evaluate to a string with a + in the middle of it since the quotes are wrapped around both elements. correct way to write it would be "$($_.name)$($_.user)" or more likely if the source file does not place a trailing '\' on the name field
"$($_.name)\$($_.user)"

Need to remote access second hops via powershell with invoke-command

I struggle a lot of time regarding this problem now and asked already in another forum, which helped to approach to the solution but finally I didn't achieve it.
I "simply" need to gather information about hosts inside clouds here in our company with the help of a powershell script. You can reach the clouds via a jumphost from the local network, the jumphost is a part of the cloud as well. Then from the jumphost you can reach all cloudhosts.
So I have tried this with 2 pssessions and used invoke-command (same password for jumphost and cloudhost):
$cred = Get-Credential ad\username -Message "Please insert the password for the jumphost and the cloudhost"
$session = New-PSSession -ComputerName jumphost -Credential $cred
$cldhost = Read-Host "Please insert the name of the cloudhost"
$script = {
Param (
$Credential,
$cloudhost
)
$ses = New-PSSession -ComputerName $cloudhost -Credential $Credential
Invoke-Command -Session $ses -ScriptBlock { Get-ChildItem C:\ }
Remove-PSSession $ses
}
Invoke-Command -Session $session -ScriptBlock $script -ArgumentList $cred, $cldhost
Remove-PSSession $session
But this always gives me the output of C:\ of the jumphost and not of the cloudhost.
In the other forum I was advised to use credssp or delegated sessions.
CredSSP is not possible here, because I get the error that the SPN is missing in the AD-account and I'm not allowed to add one and the delegated sessions don't help me, because I have admin rights on the jumphost and the cloudhost and don't need to delegate something.
But anyway I think it's not a problem of the credentials, because I get no "Access denied" error or something else and enter-pssession to the jumphost and from there invoke-command to the cloudhost works without a problem, but I can't use this in a script.
Something seems to be wrong in the logic of the nested pssessions code...
Do you have any idea to make this work proper here?
delegated admin rights:
http://blogs.technet.com/b/heyscriptingguy/archive/2014/04/03/use-delegated-administration-and-proxy-functions.aspx
CredSSP:
http://blogs.technet.com/b/heyscriptingguy/archive/2012/11/14/enable-powershell-quot-second-hop-quot-functionality-with-credssp.aspx
Thanks a lot,
Marc
By the way:
I've tried to use CredSSP, because it is recommend to use it for second hops:
Enable-WSManCredSSP -Role Client -DelegateComputer jumphost -Force
$cred = Get-Credential ad\username -Message "Please insert the password for the jumphost and the cloudhost"
$session = New-PSSession -ComputerName jumphost -Credential $cred
Invoke-Command -Session $session -ScriptBlock {Enable-WSManCredSSP -Role Server –Force; Set-Item wsman:\localhost\client\trustedhosts -value localcomputer -Force; Restart-Service winrm -Force}
$session2 = new-PSSession -ComputerName jumphost -Credential $cred -Authentication Credssp
After entering this last command I get the following error:
The WinRM client cannot
process the request. A computer policy does not allow the delegation of the user credentials to the target computer because the
computer is not trusted. The identity of the target computer can be verified if you configure the WSMAN service to use a valid
certificate using the following command: winrm set winrm/config/service '#{CertificateThumbprint="<thumbprint>"}' Or you can
check the Event Viewer for an event that specifies that the following SPN could not be created: WSMAN/<computerFQDN>. If you find
this event, you can manually create the SPN using setspn.exe . If the SPN exists, but CredSSP cannot use Kerberos to validate
the identity of the target computer and you still want to allow the delegation of the user credentials to the target computer,
use gpedit.msc and look at the following policy: Computer Configuration -> Administrative Templates -> System -> Credentials
Delegation -> Allow Fresh Credentials with NTLM-only Server Authentication. Verify that it is enabled and configured with an SPN
appropriate for the target computer. For example, for a target computer name "myserver.domain.com", the SPN can be one of the
following: WSMAN/myserver.domain.com or WSMAN/*.domain.com. Try the request again after these changes. Weitere Informationen
finden Sie im Hilfethema "about_Remote_Troubleshooting".
In Zeile:1 Zeichen:13
+ $session2 = new-PSSession -ComputerName jumphost -Credential $cred -Aut ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (System.Manageme....RemoteRunspace:RemoteRunspace) [New-PSSession], PSRemotingTransportE
xception
+ FullyQualifiedErrorId : -2144108124,PSSessionOpenFailed
I do not know what to avtivate further to use CredSSP, anyway it would be better to make it work without CredSSP.
Ok additionally:
It should work with delegated sessions, I have tried the following:
on the Jumphost:
Register-PSSessionConfiguration -Name PowerShell.Session -SessionType DefaultRemoteShell -AccessMode Remote -RunAsCredential 'ad\username' -ShowSecurityDescriptorUI –Force
And then granted access to the user 'ad\username' (Invoke and Read access).
After that I was able to use the session configuration on the jumphost with the follwoing commands:
$cred = Get-Credential ad\username -Message "Please enter the password for jumphost"
$session = New-PSSession -ConfigurationName PowerShell.Session -ComputerName jumphost -Credential $cred
So the session was connected and I entered my other commands:
$cldhost = Read-Host "Please enter the cloudhost name"
$script = {
Param (
$Credential,
$Hostname2
)
$ses = New-PSSession -ComputerName $Hostname2 -Credential $Credential
Invoke-Command -Session $ses -ScriptBlock { Get-ChildItem C:\ }
Remove-PSSession $ses
}
Invoke-Command -Session $session -ScriptBlock $script -ArgumentList $cred, $cldhost
Remove-PSSession $session
Unfortunately I get the output of Get-ChildItem C:\ of the jumphost again and not the output of the cloudhost...
Do you have any further idea? Is maybe the $script{} part somewhere wrong?
Finally it works:
$cred = Get-Credential ad\username -Message "Please insert the password for the jumphost"
$session = New-PSSession -ComputerName jumphost -Credential $cred
$cldhost = Read-Host "Please insert the cloudhost name"
$script = {
Param (
$Credential,
$Hostname2
)
$ses = New-PSSession -ComputerName $Hostname2 -Credential $Credential
Invoke-Command -Session $ses -ScriptBlock { Get-ChildItem C:\ }
Remove-PSSession $ses
}
Invoke-Command -Session $session -ScriptBlock $script -ArgumentList $cred, $cldhost
Remove-PSSession $session
This means I do not need the delegated sessions or CredSSP. But anyway, it works as well by manual setting the delegated configuration on the jumphost and then adding the users who should be able to connect to the session configuration in the pop-up -ShowSecurityDescriptorUI and delete the default users "interactive user" and local administrators:
Register-PSSessionConfiguration -Name PowerShell.Session -SessionType DefaultRemoteShell -AccessMode Remote -RunAsCredential 'ad\username' -ShowSecurityDescriptorUI –Force
If you now connect to the session configuration with a above specified user the commands will be executed in context of the user you have specified under -RunAsCredential.
It is also working directly from the local host, but you have to use -SecurityDescriptorSddl and this requires a function which deletes the default credentials for the session configurations and adds the new credential with ACLs automatically...means a lot of work.
Thanks a lot for the help!
Marc