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.
Related
i have an problem with my script, plz help :3
This script is supposed to get all Server Hostnames from our Server OU. And than get the Used and Free Space of the Servers But when i try to get the server list with the "Get-AdComputer" cmdlet i get errors.
$servers = Get-ADComputer -Filter * -SearchBase "OU=SomeOU, DC=SomeDomain, DC=SomeDomain, DC=SomeDomain" | Select-Object Name
$allDisks = foreach ($server in $servers)
{
Get-WmiObject Win32_LogicalDisk -ComputerName $server -Filter DriveType=3 |
Select-Object #{'Name'='ComputerName'; 'Expression'={$server}},
DeviceID,
#{'Name'='Size'; 'Expression'={[math]::truncate($_.size / 1GB)}},
#{'Name'='Freespace'; 'Expression'={[math]::truncate($_.freespace / 1GB)}}
}
$allDisks |Export-Csv C:\Servers.csv -NoTypeInformation
when i run this i get:
Get-WmiObject : Der RPC-Server ist nicht verfügbar.
In Zeile:5 Zeichen:5
+ Get-WmiObject Win32_LogicalDisk -ComputerName $server -Filter Dri ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
i also should add, that if i only run the thing from the first line i get an clean list of all of our servers.
As the error states that RPC server is not available for the one of the servers that you are trying to query. There can be multiple reasons as per the PS Blog:
The remote computer is blocked by the firewall.
Solution: Open the Group Policy Object Editor snap-in (gpedit.msc) to edit the Group Policy object (GPO) that is used to manage Windows Firewall settings in your organization. OpenComputer Configuration, open Administrative Templates, open Network, open Network Connections, open Windows Firewall, and then open either Domain Profile or Standard Profile, depending on which profile you want to configure. Enable the following exception: “Allow Remote Administration Exception” and “Allow File and Printer Sharing Exception“.
Hostname or IP address is wrong or the remote computer is shut down.
Solution: Verify correct hostname or IP address.
The “TCP/IP NetBIOS Helper” service isn’t running.
Solution: Verify that “TCP/IP NetBIOS Helper” is running and set to auto start after restart.
The “Remote Procedure Call (RPC)” service is not running on the remote computer.
Solution: Verify that “Remote Procedure Call (RPC)” is running and set to auto start after restart.
The “Windows Management Instrumentation” service is not running on the remote computer.
Solution: Verify that “Windows Management Instrumentation” is running and set to auto start after restart
So, I dont think there is any code issue there. Kindly check the network firwwall and server side. Also apply a try/catch block and capture the exact server name in the loop to see which server is that causing the issue.
I am just trying to write a script that can remote login with user/pass credentials via Jenkins. I wrote this script that is given below;
$pass = convertto-securestring "SOME_PASSWORD" -asplaintext -force
$mycred = new-object -typename System.Management.Automation.PSCredential -argumentlist "SOME_USERAME",$pass
invoke-command "SOME_COMPUTER_NAME" {get-process} -credential $mycred
After running this script it giving error like;
[SOME_COMPUTER_NAME] Connecting to remote server SOME_COMPUTER_NAME 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: (SOME_COMPUTER_NAME:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : WinRMOperationTimeout,PSSessionStateBroken
Before your question and suggestions; just controlled WinRM service local and remote machines, I enabled PSRemoting and Set-Item TrustedHosts on remote machine.
I am trying to connect to exchange remotely and run queries from Powershell.
This is my configuration file on the Exchange server:
Register-PSSessionConfiguration -Name "Exchange" -StartupScript "C:\ProgramFiles\Microsoft\Exchange Server\V14\Bin\RemoteExchange.ps1"
This is how I am connecting from my local computer:
$s = New-PSSession -ComputerName cmsexch -ConfigurationName "Exchange" -Authentication Kerberos -credential $cred
And this is the error message I am getting:
New-PSSession : Running startup script threw an error: Cannot find path 'HKLM:\Software\microsoft\ExchangeServer\v14\CentralAdmin' because it does
not exist..
NOTE:
My local Powershell is running on Windows 2008 SP2 32 bits
My remote Exchange is running on Windows 2008 R2 SP1 64 bits
QUESTIONS:
How can I fix this issue?
Is this because the registry redirector on
Windows 64 bits?
Thank you very much
The connection string from your local computer appears to be missing a few things. I believe that the following code is what you're looking for. You would need to fill in your FQDN and that's about it. These 3 lines get me right in. The 32/64 bit should make no difference.
$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://<FQDN of your Exchange server>/PowerShell/ -Authentication Kerberos -Credential $UserCredential
Import-PSSession $Session
This TechNet Exchange Knowledge Article might elaborate or at least point you in the right direction.
http://technet.microsoft.com/en-us/library/dd335083%28v=exchg.150%29.aspx
While login to windows with local administrator and install xendesktop with AD administrator account, it's successful, below is what i have done:
$adPassword= convertto-securestring "password" -asplaintext -force
$adCredObject = new-object -typename System.Management.Automation.PSCredential -argumentlist "ad.mydomain.com\user",$adPassword
$CurrentProcess = Start-Process -FilePath ".\xendesktop\x64\XenDesktop Setup\XenDesktopServerSetup.exe" -Credential $adCredObject -Wait -PassThru -ArgumentList "/COMPONENTS CONTROLLER,DESKTOPSTUDIO,DESKTOPDIRECTOR,LICENSESERVER,STOREFRONT /NOREBOOT /CONFIGURE_FIREWALL"
But while use puppet automation script(it run with windows system user) to execute install xendesktop with AD administrator account, it's failed, below is what i have done to run 'exec' in puppet(same code as above):
$adPassword= convertto-securestring "password" -asplaintext -force
$adCredObject = new-object -typename System.Management.Automation.PSCredential -argumentlist "ad.mydomain.com\user",$adPassword
$CurrentProcess = Start-Process -FilePath ".\xendesktop\x64\XenDesktop Setup\XenDesktopServerSetup.exe" -Credential $adCredObject -Wait -PassThru -ArgumentList "/COMPONENTS CONTROLLER,DESKTOPSTUDIO,DESKTOPDIRECTOR,LICENSESERVER,STOREFRONT /NOREBOOT /CONFIGURE_FIREWALL"
So the only difference is the succeed one run the above script with local administerator and failed one run with windows system user.The failure message display in the event log is like():
An account failed to log on.
Subject:
Security ID: SYSTEM
Account Name: MyMachineName
Account Domain: MyDomainName
Logon ID: 0x3e7
Logon Type: 3
Account For Which Logon Failed:
Security ID: NULL SID
Account Name: Administrator
Account Domain: MyMachineName
Failure Information:
Failure Reason: Unknown user name or bad password.
Status: 0xc000006d
Sub Status: 0xc000006a
Process Information:
Caller Process ID: 0xd90
Caller Process Name: C:\Program Files (x86)\Puppet Labs\Puppet\sys\ruby\bin\ruby.exe
Network Information:
Workstation Name: MyMachineName
Source Network Address: -
Source Port: -
Detailed Authentication Information:
Logon Process: Advapi
Authentication Package: Negotiate
Transited Services: -
Package Name (NTLM only): -
Key Length: 0
This event is generated when a logon request fails. It is generated on the computer where access was attempted.
The Subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe.
The Logon Type field indicates the kind of logon that was requested. The most common types are 2 (interactive) and 3 (network).
The Process Information fields indicate which account and process on the system requested the logon.
The Network Information fields indicate where a remote logon request originated. Workstation name is not always available and may be left blank in some cases.
The authentication information fields provide detailed information about this specific logon request.
- Transited services indicate which intermediate services have participated in this logon request.
- Package name indicates which sub-protocol was used among the NTLM protocols.
- Key length indicates the length of the generated session key. This will be 0 if no session key was requested.
I have tried to use runasspc also to execute this installation, but I got same result. Any help would be appreciated.
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.