Security of running PowerShell command remotely? - windows

I'm new to PowerShell. I'm looking to run PowerShell command on a remote PC running Windows 7.
On the remote PC, I ran the following PowerShell commands:
Enable-PSRemoting -Force
Set-Item WSMAN:\localhost\client\trustedhosts <host_ip>
Restart-Service WinRM
I performed the last two commands on the host PC (but using <remote_ip>).
I confirmed this worked OK with:
Invoke-Command -ComputerName <name> -Credential <username> -ScriptBlock { Get-ChildItem C:\ }
My question: Is this secure on a public network? Should I be doing something else? Or should I be using SSL? If so, how do I go about this?

If you use the default authentication when using Invoke-Command the user is authenticated on the remote host using either NTLM or Kerberos. So I don't think you need to worry too much about the password being sniffed out on the network. Also, by default, remoting endpoints can only be used by administrators on that machine. Finally, if you need to allow non-admins access, you can configure a remoting endpoint that is restricted. It can be restricted in the cmdlets available and it can be restricted in language capability. This tutorial on remoting covers setting up a restricted session.

Related

Invoke Powershell 7 commands in Hyper-V VM without Admin

I'm trying to use Powershell to remotely perform actions within a Windows 10 Hyper-V VM from the Windows 11 host. These actions must:
Be run in the guest OS using Powershell 7
Be run in the guest OS without administrator priviledges (runas /trustlevel:0x20000 <cmd> doesn't work for these actions)
Be run in the guest OS synchronously with it's output captured (i.e. usual de-elevation techniques such as scheduled tasks / explorer.exe <cmd> aren't applicable)
While I am able to run non-elevated commands in Powershell 5.1, I am not able to do so using Powershell 7 as, no matter what I try (see below), a user without administrative priviledges isn't able to use the Powershell 7 session configurations.
My hunch is that the Powershell 7 session configurations (which need to be created while running as Administrator) have file permissions which are not accessible to non-administrative users but I've not been able to find the associated files and verify this.
Stuff I have tried is below. Any suggestions much appreciated.
Powershell 5.1
I can execute regular Powershell 5.1 commands using Invoke-Command, New-Session, Enter-Session, etc using:
Invoke-Command -VMName $vmName -Credential $creds -ScriptBlock { $PSVersionTable }
Which shows this command has been executed using PSVersion 5.1:
Name Value
---- -----
WSManStackVersion 3.0
BuildVersion 10.0.19041.1682
PSVersion 5.1.19041.1682
SerializationVersion 1.1.0.1
CLRVersion 4.0.30319.42000
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
PSEdition Desktop
And works regardless of whether or not the user for specified credentials has administrator priviledges in the guest OS. This can be checked using:
Invoke-Command -VMName $vmName -Credential $creds -ScriptBlock { whoami /groups }
Which results in the following when the user is in the Administrator group:
Group Name
=============================================================
Everyone
NT AUTHORITY\Local account and member of Administrators group
BUILTIN\Users
BUILTIN\Administrators
NT AUTHORITY\INTERACTIVE
CONSOLE LOGON
NT AUTHORITY\Authenticated Users
NT AUTHORITY\This Organization
NT AUTHORITY\Local account
NT AUTHORITY\NTLM Authentication
And the following when the user is not in the Administrator group:
Group Name
======================================
Everyone
BUILTIN\Users
NT AUTHORITY\INTERACTIVE
CONSOLE LOGON
NT AUTHORITY\Authenticated Users
NT AUTHORITY\This Organization
NT AUTHORITY\Local account
NT AUTHORITY\NTLM Authentication
Powershell 7
Running Enable-PSRemoting in an elevated Powershell 7 session within the guest OS creates additional session configurations which can be seen using Get-PSSessionConfigration as shown below:
Name : PowerShell.7
PSVersion : 7.3
StartupScript :
RunAsUser :
Permission : NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote
Management Users AccessAllowed
Name : PowerShell.7.3.0
PSVersion : 7.3
StartupScript :
RunAsUser :
Permission : NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote
Management Users AccessAllowed
If the user for the specified credentials is in the Administrators group, these configurations can then be used to execute commands in Powershell 7, for example:
Invoke-Command -VMName $vmName -Credential $creds -ConfigurationName PowerShell.7 -ScriptBlock { $PSVersionTable }
Which shows this command has been executed using PSVersion 7.3:
Name Value
---- -----
WSManStackVersion 3.0
OS Microsoft Windows 10.0.19044
PSVersion 7.3.0
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
GitCommitId 7.3.0
Platform Win32NT
PSEdition Core
However, if the user for specified credentials is not in the Administrators group then an error is encountered when executing the same command:
OpenError: Cannot create or open the configuration session PowerShell.7.
Adding User to "Remote Management Users"
Given then PSSession Configurations shown above seem to suggest a user in the Remote Management Users group should have AccessAllowed I have tried adding this group to the user for the specified credentials. This is shown by executing the following command in Powershell 5.1:
> Invoke-Command -VMName $vmName -Credential $creds -ScriptBlock { whoami /groups }
Group Name
======================================
Everyone
BUILTIN\Users
BUILTIN\Remote Management Users
NT AUTHORITY\INTERACTIVE
CONSOLE LOGON
NT AUTHORITY\Authenticated Users
NT AUTHORITY\This Organization
NT AUTHORITY\Local account
NT AUTHORITY\NTLM Authentication
Mandatory Label\Medium Mandatory Level
But results in the same error when executing the command in Powershell 7:
> Invoke-Command -VMName $vmName -Credential $creds -ConfigurationName PowerShell.7 -ScriptBlock { whoami /groups }
OpenError: Cannot create or open the configuration session PowerShell.7.
Adding User/Users group to Powershell.7 Session Configuration
I have tried add the specific user and/or the Users group to the Powershell.7 Session Configuration using:
Set-PSSessionConfiguration -Name PowerShell.7 -ShowSecurityDescriptorUI
But the user for the specified credentials is still unable able to access the configuration:
> Invoke-Command -VMName $vmName -Credential $creds -ConfigurationName PowerShell.7 -ScriptBlock { whoami /groups }
OpenError: Cannot create or open the configuration session PowerShell.7.
Changing Default Session Configuration
I have also tried setting the default (Microsoft.PowerShell) session configuration to PowerShell 7 by using the script shown here which executes correctly and can be verified using the command:
> Get-PSSessionConfiguration -Name Microsoft.PowerShell
Name : Microsoft.PowerShell
PSVersion : 7.3
StartupScript :
RunAsUser :
Permission : NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote
Management Users AccessAllowed
But commands still seem to be invoked using Powershell 5.1 as shown:
> Invoke-Command -VMName $vmName -Credential $creds -ScriptBlock { $PSVersionTable }
Name Value
---- -----
WSManStackVersion 3.0
BuildVersion 10.0.19041.1682
PSVersion 5.1.19041.1682
SerializationVersion 1.1.0.1
CLRVersion 4.0.30319.42000
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
PSEdition Desktop
Aaaaaaand, now I'm out of ideas. I could possibly move to using Powershell remoting over SSH but this has it's own set of challenges (generating and adding keys, VM being accessible/resolvable on the external network, etc) so I'm really hoping there's a simply solution to the above.
Help me Stackoverflow Kinobi, you're my only hope.
But the user for the specified credentials is still unable able to access the configuration:
Invoke-Command -VMName $vmName -Credential $creds -ConfigurationName PowerShell.7 -ScriptBlock { whoami /groups }
OpenError: Cannot create or open the configuration session PowerShell.7.
I think there is catch, even if you set standard user to be allowed remote access you still need to use an elevated PS console to execute commands.
when I run the command in the console that was open as standard user the command fails with same error you posted, but opening it as Admin worked by specifying standard user credentials, ex.
In VM run:
Enable-PSRemoting
$SessionName = "StandardSession"
Register-PSSessionConfiguration -Name $SessionName -AccessMode Remote
# When the security dialog shows up, add "Users" to list and set "full controll"
Set-PSSessionConfiguration -ShowSecurityDescriptorUI -Name $SessionName -AccessMode Remote
On host system open PS as Admin and run:
# Add VM name to trusted hosts, update this to VM host name
$Domain = "VM_NETBIOS_NAME"
Set-Item -Path WSMan:\localhost\client\TrustedHosts -Value $Domain -Concatenate
# Restart WinRM service for changes to take effect
Restart-Service -Name WinRM
# Enter credentials of standard user account in VM
$creds = Get-Credential
Invoke-Command -ComputerName $Domain -Credential $creds -ScriptBlock { $PSVersionTable } -ConfigurationName "StandardSession"
Although I didn't test these commands exactly but as part of my other setup which works, by using these commands I got pwrshplugin.dll error but you might get different result, which if you get the same can run the following to confirm all plugins are enabled:
Get-Item WSMan:\localhost\Plugin\* | ForEach-Object {
$Enabled = Get-Item "WSMan:\localhost\Plugin\$($_.Name)\Enabled" |
Select-Object -ExpandProperty Value
[PSCustomObject] #{
Name = $_.Name
Enabled = $Enabled
PSPath = $_.PSPath
}
} | Sort-Object -Property Enabled -Descending | Format-Table -AutoSize
Likely an elevated PS on host isn't a solution you seek but keep in mind that there is registry setting in:
HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy
Which allows remote access to members of the Administrators group.
This setting is implicitly set by Enable-PSRemoting
This option is needed to avoid UAC.
I think problem is that for Administrators you can disable UAC but you can't disable UAC for standard users in Windows, but remoting requires this option to be set.
Also this registry option exists only for HKEY_LOCAL_MACHINE, there is no equivalent per-user setting in HKEY_USERS to allow remote access to User.
Hopefully this might shade some light or help to troubleshoot issues, sadly I'm unable to make a reproducible example out of my setup.
EDIT:
On host system in an elevated PS I've run:
# note that $creds are standard user creds of a user in VM
Invoke-Command -ComputerName $Domain -Credential $creds -ScriptBlock { $PSVersionTable } -ConfigurationName "CustomSession"
And got an error:
OpenError: [VM-PRO] Connecting to remote server VM-PRO failed with the following error message : <f:WSManFault xmlns:f="http://schemas.microsoft.com/wbem/wsman/1/wsmanfault" Code="2689860592" Machine="VM-PRO"><f:Message><f:ProviderFault provider="CustomSession" path="C:\Windows\system32\PowerShell\7.3.1\pwrshplugin.dll"></f:ProviderFault></f:Message></f:WSManFault> For more information, see the about_Remote_Troubleshooting Help topic.
Copy this path, in my example it's C:\Windows\system32\PowerShell\7.3.1\pwrshplugin.dll
In guest system visit path C:\Windows\system32\PowerShell\7.3.1 and grant write permission to Users group on this directory.
See this: issue for more information.
Then again I run the command and it succeeded:
Invoke-Command -ComputerName $Domain -Credential $creds -ScriptBlock { $PSVersionTable } -ConfigurationName "CustomSession"
Name Value
---- -----
PSVersion 7.3.1
WSManStackVersion 3.0
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSEdition Core
OS Microsoft Windows 10.0.19045
PSRemotingProtocolVersion
Platform Win32NT
SerializationVersion 1.1.0.1
GitCommitId 7.3.1
Of course this works only if you run PS as Admin on host system to run commands as standard user in guest system.

Jenkins on Windows fails to deploy with WinRM?

I have an old established codebase that I'm trying to bring up to modern era standards. Most of it is written on Windows using Visual Studio, so I need to have a Windows based build server to use the MSBuild pipeline. I have a mostly working Jenkins CI pipeline that ingests from Github webhooks, and should deploy to a Windows PC on my local network. I've tested that this works from any other user, on my workstation and on the build server. I know Jenkins runs jobs as the "NT AUTHORITY\System" user, and I've used SysInternals PSExec to pop in and setup my ssh keys, and so forth in the past. The problem is during the deploy step; I'm compressing and copying the build output using a PowerShell script, and using New-PSSession, and Copy-Item -ToSession.
I'm using a cred I'm constructing with Get-Credential, user/pass pair, that I've verified as working. All concerned systems are in a simple workgroup, no domain involved.
The New-PSSession command in my deploy.ps1 script fails with the following error:
PS C:\Program Files (x86)\Jenkins\workspace\xxx> .\deploy.ps1
Compressing to C:\Windows\TEMP\tmpEBB2.tmp.zip
New-PSSession: C:\Program Files (x86)\Jenkins\workspace\xxx\deploy.ps1:95
Line |
95 | … $sess = New-PSSession -ComputerName $TargetHost -Credential $cred …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| [205.208.87.185] Connecting to remote server 205.208.87.185 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. Other Possible Cause: -The domain or computer name was not
| included with the specified credential, for example: DOMAIN\UserName or COMPUTER\UserName.
Write-Error: C:\Program Files (x86)\Jenkins\workspace\xxx\deploy.ps1:129
Line |
129 | Deploy-ToTargetHost
| ~~~~~~~~~~~~~~~~~~~
| Could not establish session.
I generated that second error when the $sess var fails to populate. This is line 95:
$sess = New-PSSession -ComputerName $TargetHost -Credential $cred
I believe I've heard something about the System user has some restrictions on network access? Is there any way to work around this?
I mean, I can just scp it over if there's no other way to do this, but I really wanted to just have all my shell scripting in pwsh if I could get away with it. Thanks.
[Edit: TL;DR, I suppose I can modify Jenkins to run as a different user, but why isn't it already running like that? This just seems trivially weird to me to install by default on a user with no network access, I guess?]
I ended up running Jenkins as a different user in Windows Services, specifically a "regular" login user. This made it do the deployment successfully.

POWERSHELL - Couldn't connect to a remote machine

Couldn't connect to a remote machine because of my password?
My problem here :
I can connect remotely with the normal method like "mstsc", so my user and password are working fine.
I do not understand why the password didn't work on powershell.
Could you help me for that please?
WinRM is enable on the remote machine.
Add your full command to the post for review.
You should run your powershell session as an account that has proper access to the server.
enter-pssession -computername "your PC Name" is the command.
Powershell version will matter here to the device you are trying to connect to needs to be on powershell 3.0

Mount-DiskImage giving Access Denied when running through remote session

I have two VM's(Windows server 2008 r2) with ip
172.17.178.10
and
172.17.178.11
.
I have created a folder named
"share"
on vm with ip 172.17.178.10 that has an iso.
I logined into vm with ip 172.17.178.11 and run the following command
"Mount-DiskImage \\172.17.178.10\share\xyz.iso"
.It mounted successfully i can see the Drive in my computer.
Now i logined into 172.17.178.10 and took a remote session using powershell command
Enter-PSSession -ComputerName 172.17.178.11 -Credential Administrator
.
Now when i run the command
"Mount-DiskImage \\172.17.178.10\share\xyz.iso"
.
I get the following error:
MOUNT-DISKIMAGE : Access is denied.
+ CategoryInfo : PermissionDenied: (MSFT_DiskImage:ROOT/Microsoft/.../MSFT_DiskImage) [Mount-DiskImage],
CimException
+ FullyQualifiedErrorId : HRESULT 0x80070005,Mount-DiskImage
I have provided full permissions to the
share
folder.
The issue here is that powershell remoting will not allow for a second-hop authentication unless credssp is enabled. Basically what happens is that when when authenticate to the server you are remoting to it only verifies that you have access to it, it does not actually store your credentials for security reasons, so it is not able to connect to any other server in your environment. I've attached some links below with info on setting up CredSSP, which will allow you to perform second-hop remoting once it is configured.
https://support.microsoft.com/en-us/kb/951608
https://technet.microsoft.com/en-us/library/hh849872.aspx
you could also probably set your share/NTFS permissions to allow everyone read permissions but I have not tested that.

Re-enable Remote Desktop Windows Firewall Rule on Windows Azure

I have disabled the remote desktop firewall rule in a Windows Azure virtual machine.As you would expect, I can no longer remote desktop in to the server.
Does anyone know if it is possible to re-enable the Remote Desktop Windows firewall rule?
What I have tried
As a long shot, I have downloaded the Windows Azure CLI but can't see anything in there that would do it but have not found anything.
I have also tried to execute the following command against the MSSQL server:
EXEC xp_cmdshell 'netsh advfirewall firewall set rule group="remote desktop" new enable=Yes';
GO
I am getting the following message from the query:
The requested operation requires elevation (Run as administrator).
Please tell me I don't have to re-create the site (which is backed up).
If you're using a VM inside a resource group with the new azure portal, you can do this:
Click reset password
Change mode to "Reset configuration only"
Click update and wipe your sweat off :)
It turns out that all I needed to do was to PowerShell into the Azure VM.
Steps:
Make sure PowerShell is enabled in the Endpoints section of the Azure portal.
Get the server's certificate (PowerShell needs this for remote commands). You can get the server certificate by going to your domains' URL: https://yourdomaing.cloudapp.net:12345 (where :12345 is the port that PowerShell uses).
Export the SSL certificate of the site as a .CER file and install it on your local machine.
Save it to the "Trusted Root Certification Authorities" store on your machine.
Open PowerShell with administrative privileges on your local machine and type:
Enter-PSSession -ComputerName yourdomain.cloudapp.net -Port 5986 -Credential YourUserName -UseSSL
A login popup will appear, enter your VM's login credentials here.
You will now be able to execute commands against the Azure VM. In my case, I ran netsh advfirewall firewall set rule group="remote desktop" new enable=Yes and exited the PowerShell session and was able to remotely connect to my machine.

Resources