Invoke-Command runs OK as Administrator, but not as current user - powershell

The following code works fine when I run it in the PowerShell ISE as Administrator (i.e. I start the PS ISE as Admin)
Invoke-Command -ScriptBlock {[IntPtr]::Size}
Invoke-Command -ScriptBlock {[IntPtr]::Size} -ComputerName $env:COMPUTERNAME -Credential $Credential
Invoke-Command -ScriptBlock {[IntPtr]::Size} -ComputerName $env:COMPUTERNAME -Credential $Credential -ConfigurationName Microsoft.PowerShell32
I get the expected responses of
8
8
4
This tells me that WinRM is correctly configured and running, and that my $Credential is correctly setup. However, when I try running the same in the PS ISE as a user (with or without Admin rights) I get the following errors for the second and third commands
[<ComputerName>] Connecting to remote server <ComputerName> failed with the following error message : Access is denied. For more information, see the about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (<ComputerName>:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : AccessDenied,PSSessionStateBroken
I will be substituting the ScriptBlock code with something more substantive, that needs to run in 32 bit mode because of dependencies on 32 bit DLLs, and the ability for users to run some of the code in 64 bit mode and other parts in 32 bit mode is important.
Any thoughts?

PSRemoting uses an endpoint, or session configuration, on the remote computer. You're obviously aware of this, as your third command includes the ConfigurationName parameter. These endpoints -- Microsoft.PowerShell, Microsoft.PowerShell32, etc. -- include permissions on them that indicate who can connect to them.
Go to your remote computer (your local computer in this instance), and run Get-PSSessionConfiguration and take a look at the Permission property. You'll quickly realize that you administrative access is a requirement. This is by design; it's a good thing!
Your options are to one, edit the endpoint(s) and add your user(s), two, grant required access to your user (whether that be Admin or potentially Remote Management Users access), three, use a credential object when you run Invoke-Command, passing the credentials, or four, creating your own endpoint with the necessary permissions.

Related

Remote Powershell scripting and Jenkins not working

I am having an issue running a remote script using Jenkins. I have installed the PowerShell plug-in and can run PowerShell scripts on the local build server, but when I try to run it on a remote server, it fails all the time. I can run the same script outside of Jenkins locally and remotely and it works just fine. My assumption is that there is a security setting I am missing but for the life of me, I can not find it.
Any insight/help would be greatly appreciate it.
The code below runs using PowerShell on the server but not through Jenkins:
$ErrorActionPreference = 'Stop'
# Create a PSCredential Object using the "User" and "Password" parameters
that you passed to the job
$SecurePassword = 'xxxxxxx' | ConvertTo-SecureString -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList 'ci-user', $SecurePassword
# Invoke a command on the remote machine.
# It depends on the type of job you are executing on the remote machine as
to if you want to use "-ErrorAction Stop" on your Invoke-Command.
Invoke-Command -ComputerName xxx.xx.xx.xxx -Credential $cred -ScriptBlock {
# Restart the W32Time service
Restart-Service -Name W32Time
}
The error below is what I get when I run it in Jenkins. I am using the same username and password when I run it outside of Jenkins and works:
Connecting to remote server xxx.xx.xx.xxx failed with the
following error message : WinRM cannot process the request. The following
error with errorcode 0x8009030d occurred while using Negotiate authentication:
A specified logon session does not exist. It may already have been terminated.
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:\Windows\TEMP\jenkins3589460126620702793.ps1:12 char:1
+ Invoke-Command -ComputerName xxx.xx.xx.xxx -Credential $cred -ScriptBlock {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (xxx.xx.xx.xxx:String) [], PSRemoting
TransportException
+ FullyQualifiedErrorId : 1312,PSSessionStateBroken
This could be caused by a few different issues:
Are your remote machine and connecting machine on the same domain? If not, verify the domain of your ci-user and retry.
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList
'connectingserver/ci-user', $SecurePassword
Is WinRM enabled on your remote server, is the WinRM service running, are you setup to allow the appropriate remoting? Follow these steps to verify: https://technet.microsoft.com/en-us/library/ff700227.aspx?f=255&MSPPError=-2147217396
Are both the remote and connecting server setup with the same authentication method? You will want to use either Kerberos or CredSSP. I would consider CredSSP only if you are trying to solve the Double-Hop issue.
I found the error of my ways but hopefully this answer will help anyone else that encounters it.
The problem was that the user I am using is a local user and it needs to be treated as a workgroup user. So instead of ci-user, I needed to pass it as \ci-user. Once I did this, it works like a charm.
Thank you for all your input.

Powershell remoting does not have the correct permissions

On the non-domain server SERVER I have a local administrator account USER.
On the domain client machine I am running as a domain user.
Using the following code I attempt to view all services on SERVER
$cred = Get-Credential "SERVER\USER"
Invoke-Command -ComputerName SERVER -ScriptBlock {Get-Service} -Credential $cred
However, I receive the following error
Cannot open Service Control Manager on computer '.'. This operation might require other privileges.
+ CategoryInfo : NotSpecified: (:) [Get-Service], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.GetServiceCommand
Yet, if I RDP to SERVER as USER, I can manually open a Powershell window and run Get-Service without any issues. What's going on?
When remoting cross-domain, the remote command/session will not run with administrative rights. Even though you're connecting as a local admin, the resulting PSSession will not be elevated.
To fix this, you need to set the registry key LocalAccountTokenFilterPolicy located in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System to 1. See Microsoft for more details

PowerShell Remote Access Configuration

Trying to configure remote PowerShell access on a server but cannot avoid access denied errors.
What I have done:
Register-PSSessionConfiguration
-Name EngrStudentAdmin
-RunAsCredential domain\delegatedAdmin
-StartupScript 'C:\Scripts\Students\Welcome.ps1'
-ShowSecurityDescriptorUI
(on a single line - displaying above for readability)
Using the permissions GUI, I granted the group DelegatedAdmins Read and Execute permissions. The startup script is just filler.
$welcome = 'Welcome to ' + $env:COMPUTERNAME
Write-Host $welcome
Attempting to connect to the endpoint with
Invoke-Command
-ComputerName $server
-ConfigurationName EngrStudentAdmin
-ScriptBlock { hostname }
fails with the error
AuthorizationManager check failed.
+ CategoryInfo : OpenError: (engr-mgr1.domain.edu:String) [], RemoteException
+ FullyQualifiedErrorId : PSSessionStateBroken
The execution policy on the server is RemoteSigned and the startup script is signed.
The account used to access the server is a member of the DelegatedAdmins group.
Opening a local shell as delegatedAdmin shows that the account has permission to run the startup script.
Using a member of the local admins group, the Invoke-Command, without the ConfiguationName switch (i.e. connecting to the default endpoint), executes so the winrm service is running and PSRemoting enabled.
The delegatedAdmin account has no profile.
What am I missing?
Check that the WMI service is enabled and running, if it's disabled try starting it and then retrying.
Also check the properties of the actual file, it might have been blocked.
are both Domain joined? If not you might take several further steps.
In general: Try this on the remote system: Enable-PSRemoting -Force -Verbose If you see nothing, it was already applied. If not, this will make alle necessary changes for you.
Just in case: Check your Firewall settings :-)
As Dewi mentioned: Check the WMI Service.
Here is a quick hack to enable it (if you want to enforce it):
# Configure WMI
Set-Item -Path wsman:\localhost\client\trustedhosts -Value * -Force -Confirm:$False
# Restart
Restart-Service -Name WinRM -Force
Last but not least: Use the -verbose switch to see more details.
Like this:
New-PSSession -ComputerName $ComputerName -Credential $credencial -Verbose
Cheers
Josh

Running a Setup.exe from a network share, via Invoke-Command in Powershell

PSEXEC started to give me some trouble, and I decided to recode in PowerShell.
This batch command used to work for me, before PSEXEC started messing things up:
psexec -accepteula \\<ServerToBeUpdated> -u <User> -p <Password> cmd /c "\\<ServerWithInstallationFile>\SystemEnv\Bin\Setup.exe /silent /Update"
I'm trying to do this with Invoke-Command in Powershell, but with no luck so far.
I've tried many combinations, and googled a lot, and overall it seems that PowerShell is not fond of the UNC path I'm trying to install from.
Here is what I've got:
Invoke-Command -ComputerName <ServerToBeUpdated> -ScriptBlock { Start-Process -FilePath "\\<ServerWithInstallationFile>\SystemEnv\Bin\Setup.exe" -ArgumentList "/update /silent" -wait }
I get this error message:
This command cannot be run due to the error: Access is denied.
+ CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOperationException
+ FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand
+ PSComputerName : DE5441
Some people say that the setup.exe has be copied locally on the remote server. But this does not seem to be an option for me, mainly for two reasons.
My setup.exe identifies that it is not in the right path, then it kills the local the setup.exe process, and automatically starts a new setup.exe from the UNC path.
I also need the ExitCode from my setup.exe, which gets lost when the "killing" starts as mentioned in reason number 1.
As a final note, I did grant access for PowerShell to run remotely with the Enable-PSRemoting command, and I also get expected results from this simple test:
Invoke-Command -ComputerName <ServerToBeUpdated> -ScriptBlock { Hostname }
You are experiencing a so called double-hop authentication issue. If using normal authentication you will not be able to authenticate to a second computer from the machine you are invoking the command on.
To solve this you can use CredSSP.
To enable CredSSP on the machine that is being called:
Enable-WSManCredSSP -Role Server -force
To enable CredSSP on the client:
Enable-WSManCredSSP -Role Client -DelegateComputer server.domain.com -force
The -delegateComputer parameter expects a FQDN but also takes wildcards.
After enabling CredSSP you can use it to invoke your command with the parameter -authentication CredSSP

Cannot create remote powershell session after Enable-PSRemoting

I can not remote into any machine to save my life! I have tried everything I can find. If anyone could troubleshoot or guide me, I'd appreciate it as this would be a great tool to add on my domain.
SETUP:
Client machine inside domain
Server machine inside or outside domain - Virtualized and utilized for WSUS Computername: wsustest
CLIENT SERVER MACHINE physical- computername: epizzi-pc
STEPS:
enable-pssremoting done! on all machines
trustedhosts configured with * or client machine added
Firewalls with public profile off just in case
Enter-PSSession -ComputerName wsustest -Credential wsustest\administrator
Enter-PSSession -ComputerName epizzi-pc -Credential epizzi-pc\administrador
Enter-PSSession : Connecting to remote server epizzi-pc 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.
At line:1 char:1
+ Enter-PSSession -ComputerName epizzi-pc -Credential epizzi-pc\administrador
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (epizzi-pc:String) [Enter-PSSession], PSRemotingTransportException
+ FullyQualifiedErrorId : CreateRemoteRunspaceFailed
Enter-PSSession -ComputerName wsustest -UseSSL -Credential wsustest\administrator
*Enter-PSSession : Connecting to remote server wsustest 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 wsustest -UseSSL -Credential wsustest\administrato ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (wsustest:String) [Enter-PSSession], PSRemotingTransportException
+ FullyQualifiedErrorId : CreateRemoteRunspaceFailed*
ERRORs:
I was receiving the same problem when remoting to a server and found this blog post very helpful - http://jeffgraves.me/2013/10/14/powershell-remoting/
For my specific case I did the following:
On the Local machine
winrm quickconfig (although this was already configured)
winrm s winrm/config/client '#{TrustedHosts="myservername.domain"}'
On the Remote machine
enable-psremoting -force
Set-PSSessionConfiguration -ShowSecurityDescriptorUI -Name Microsoft.PowerShell -Force
I got around this problem by using a fully qualified logon. Instead of "netbiosdomain\accountname", I used fqdn\accountname, as in Microsoft.com\myaccount in the get-credential prompt. May not work for everyone, but it's worth a shot.
This is how I do it. I use this on my scripts.
# This is only done once
Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File
c:\Windows\temp\securepass.txt
# Setup credentials
$SecureString = Get-Content c:\Windows\temp\securepass.txt | ConvertTo-SecureString
$mycredentials = New-Object -TypeName System.Management.Automation.PSCredential
-ArgumentList "yourDomain\userID",$SecureString
# Open remote session:
$MyRSession = New-PSSession -ComputerName Computer1 -Credential $mycredentials
-Authentication default
# Use remote session:
Enter-PSSession $MyRSession
Get rid of -UseSSL. I enabled PSRemoting and had problems with using that. I guess I could look at it later but for now it doesn't matter.
If there is no trust between the client and server computers, you have to enable basic authentication on the server side. Do this by toggling the correct properties on the WSMAN: drive on the server. You'll obviously have to do this interactively on the console or via remote desktop, due to the chicken and egg problem :) Also, this may come into play too:
http://www.nivot.org/blog/post/2009/10/30/PowerShell20EnablingRemotingWithVirtualXPModeOnWindows7
I was getting that same error currently no logon servers available.
The issue was resolved by using instead of Domain\Username as credentials the user UPN or Username#Domain.
I have achieved a remote session with Enter-pssession command, had to follow these exact parameters
$creds = get-credential (the -credential parameter in enter-pssession does not work properly, thus u must previously enter the object at another variable)
Enter-pssession -computername wsustest -authentication Default -credentials $creds
i Also had to set both client and remote server in the trusted hosts wsman: space
another solution which surely wouldve worked but i havent tried, wouldve been setting https: which is harder to do.
thx to all, your comments certainly led to the solution!