how to get winrm to use powershell 7 for remote sessions by default - powershell

With the release of powershell 7, seems like it is time to move past ps 5.1 so I have installed in on a couple of servers to give it a go.
However I when I create a session to these servers from my pc with ps7 I am always running ps5.1 on the remote machine.
Invoke-Command -ComputerName name -ScriptBlock {
Write-Host $env:COMPUTERNAME
$PSVersionTable.PsVersion
}
Which outputs 5.1.17763.316. Any ideas how to get the remote session to use version 7.0.0 preferably by default?
Update
making some progress with this, so though I would share.
On the remote machine in powershell 7 run the following command
Enable-PSRemoting
This will create some PsSessionConfigurations which you can see with the following command..
Get-PSSessionConfiguration
Now you can do the following to create sessions from powershell 7
Invoke-Command -ComputerName ServerName -ScriptBlock { $PsVersionTable.PSVersion } -ConfigurationName Powershell.7
$session = New-PSSession ServerName -ConfigurationName Powershell.7
Invoke-Command -Session $session -ScriptBlock { $PsVersionTable.PSVersion }
This now uses ps 7 on the remote session, happy days. Now how to make this happen by default...? From this github issue :
set the default microsoft.powershell endpoint to any PowerShell they
choose
Which I think is what I want to do so switched back to ps 5.1 and tried this command:
Get-PSSessionConfiguration -Name microsoft.powershell | Set-PSSessionConfiguration -PSVersion 7.0
Only to get the following output:
Set-PSSessionConfiguration : Cannot bind parameter 'PSVersion' to the
target. Exception setting "PSVersion": "The value 7.0 is not valid for
the PSVersion parameter. The available values are 2.0, 3.0, 4.0, 5.0,
5.1."
though I would try this in ps7 so switched back by running pwsh and ran the same command again to get he following...
Write-Error: No session configuration matches criteria
"microsoft.powershell".
So still not quite sure how to make ps7 the default... :(

Note:
It is the remoting client that determines what remoting endpoint (session configuration) to connect to on the server machine - see below.
Therefore, your own attempt,
# WRONG
Get-PSSessionConfiguration -Name microsoft.powershell |
Set-PSSessionConfiguration -PSVersion 7.0
is ineffective, because Set-PSSessionConfiguration modifies endpoint configurations on the server machine, it doesn't control the client's behavior.
Note that the fundamental prerequisite is that PowerShell remoting must be enabled on the server machine, which can be achieved either by opting to do so during installation via the MSI GUI installer, or by running Enable-PSRemoting - with admin privileges - later.Tip of the hat to Lars Fosdal.
Doing so from PowerShell (Core) creates the standard session configuration(s) named PowerShell.<version> that clients can opt to connect to - see below.
To list all configurations defined on a server, run Get-PSSessionConfiguration with admin privileges.
On a client machine, you can set a default for what session configuration defined on the server (remote machine) to connect to, via the $PSSessionConfigurationName preference variable.
E.g., to target PowerShell 7 by default:
# When remoting, default to running PowerShell Core v7.x on the
# the target machines:
$PSSessionConfigurationName = 'PowerShell.7'
If you add the above to your $PROFILE file, future sessions will target PowerShell 7 by default.
See this answer for more information, which also shows how to target a given server configuration in the context of individual commands.
Note: Changing what endpoint PowerShell [Core] targets by default - which as of 7.2 is still Window PowerShell - is being considered: see GitHub issue #11616.

Related

Can't enter remote powershell 7.1 session

Been able to do it against Microsoft.PowerShell (5.1), but today I hit a known issue on 5.1 with remote Copy-Item so I installed PowerShell 7 on the remote server (checking "Enable Remoting" in the installer) and am trying to get it working.
$securePassword = ConvertTo-SecureString -AsPlainText -Force -String $Password
$credential = New-Object -TypeName system.management.automation.pscredential -ArgumentList $Username, $securePassword
$session = New-PSSession $targetMachineHostName -Credential $credential -ConfigurationName "Microsoft.PowerShell"
Enter-PSSession $session
Above works. But if I change ConfigurationName to "PowerShell.7.1.0" I get:
[myserver.com.au] Connecting to remote server myserver.com.au failed with
| the following error message : <f:WSManFault
| xmlns:f="http://schemas.microsoft.com/wbem/wsman/1/wsmanfault" Code="2689860592"
| Machine="myserver.com.au"><f:Message><f:ProviderFault provider="PowerShell.7.1.0"
| path="C:\Windows\system32\PowerShell\7.1.0\pwrshplugin.dll"></f:ProviderFault></f:Message></f:WSManFault> For more information, see the about_Remote_Troubleshooting Help topic.
On the remote server I've run enable ps remoting in a 7.1 powershell so if I run Get-PSSessionConfiguration it returns a bunch of configurations, including the following:
Name : PowerShell.7.1.0
PSVersion : 7.1
StartupScript :
RunAsUser :
Permission : NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote
Management Users AccessAllowed
The dll the error refers to exists on the machine.
The user credentials I'm using are for a Local User on the remote machine that isn't an Administrator, but belongs to the Remote Management Users group.
Also worth noting from the remote machine itself (as a different Adminstrator local account, I can start a session to localhost).
After making the user an Administrator I was able to connect, but I'd gone to great lengths earlier to make non-Adminstrator possible on 5.1.
Out of interest, I tried giving the user Full Control to C:\Windows\system32\PowerShell\7.1.0 and then I could connect...
Still would love to know what's going on though and whether I'm doing the right thing or minimum permissions required.
It seems like the minimum security permissions to the folder are:
Read & Execute
List folder contents
Read
Write
Write is bizarre, but without it I get that error. I've assigned those permissions to the "Remote Management Users" group.
Docs here touch a little bit on v5.1 vs v7, and then link to here mentioning an install script so maybe something has fallen through the cracks.
I was getting the same error. I installed PowerShell 7 from Microsoft Store and then ran Enable-PSRemoting. I got this error so I uninstalled it and reinstalled it from WinGet which uses the MSI. That didn't work either. I tried running Enable-PSRemoting again, but nothing changed.
I ran Install-PowerShellRemoting.ps1 and it gave me two errors about things already existing and did not fix the problem. However, I was able to resolve the problem by doing the following:
Delete the PowerShell 7 plugins: Remove-Item 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN\Plugin\PowerShell.7','HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN\Plugin\PowerShell.7.1.1'.
Run Install-PowerShellRemoting.ps1 again.
I'm not sure what the difference was, but deleting and allowing the script to generate it again fixed it for me.

Invalid computer name error with remote execution of PowerShell script

I am trying to execute some PowerShell code in a remote computer using the following:
$session = New-PSSession -Credential "myDomain\myUserName" -ComputerName "remoteCompName"
$result = Invoke-Command -Session $session -ScriptBlock {
New-Item -type file C:\test10.txt
}
I am prompted to enter my password in a GUI. I do that. It then errors out with:
New-PSSession : One or more computer names are not valid. If you are
trying to pass a URI, use the -ConnectionUri parameter, or pass URI
objects instead of strings.
I replaced the computer name with the FQDN. Still no luck. What is going on here?
There are other questions on stackoverflow on executing PowerShell scripts on remote machines of course but none address this error.
BTW, the machine is part of the domain and is running.
Additional info added later [EDIT]
Things to know:
The machine is part of the domain and is running.
I checked if PS remoting is enabled. It was.
I checked if WinRM is running. It is.
The remote machine is a VM and it is a 2012 R2.
Here is what I've tried:
I replaced the computer name with the FQDN. Still no luck.
I removed the credential parameter
I tried another remote machine (also a VM)
I tried another source machine, i.e. the machine I am running the command from)
Thanks!
-Rohan.
When I use a remote machine with a name that is just alphanumeric (no underscores, dashes, etc.), it works! The name of all machines I tried before had leading '_' in them. That was the cause of the error. (The answer was suggested by Rhys W Edwards on the Windows PowerShell TechNet forum, which is within Windows Server forums).
Just put your ComputerName to braces like this {Remote_Computer_Name}

PowerShell Stop-Service/Start-Service not working on a specific server

I have three servers, let's call them Deploy1, Deploy2, Target.
All servers are running Windows Server 2008R2, fully updated.
A domain user, admin1, is configured as administrator on all servers, and this is the user I'm running all the commands with.
The following command works on Deploy1:
Get-Service "MyService" -ComputerName Target | Stop-Service
When running the same command on Deploy2, the command fails with the following message:
Cannot find any service with service name 'MyService'.
On Deploy2, the following command works, and displays the service and its status.
Get-Service "MyService" -ComputerName Target
Now, I know there are other ways to stop/start services via PowerShell, but I like this one as it automatically waits for the server to actually stop/start.
So what could be wrong with Deploy2?
Powershell v2.0 has a bug (feature?) in how the object returned by Get-Service is implemented. It does not actually set the ComputerName property correctly. Because of this, it can only affect local services. If you upgrade to Windows Management Framework 3.0 (and consequently Powershell v3) the bug is fixed and will work correctly.
Does this work? If not, is there an error produced?
(Get-Service "MyService" -ComputerName Target).Stop()

Get status of a process started by Invoke-WmiMethod

New to PowerShell, but loving the fact that I can do so much so quickly so far :)
Anyways, I am starting a remote process in a PowerShell script thusly:
$compname = "MY-PC"
$myinstallcmd = "c:\install\myprog.exe /s"
$proc = Invoke-WmiMethod -class Win32_Process -name Create -ArgumentList ($myinstallcmd) -ComputerName $compname
On most of the PCs I've tried, the Invoke-WmiMethod cmdlet works fine, but on one PC, it's hanging. What I'm now looking to do is get the status of the running process, and if it's hung up, kill it and log the kill, and then move on.
I did find a possible method to do this in the post
Starting a process remotely in Powershell, getting %ERRORLEVEL% in Windows - however, when I try to do the Register-WmiEvent on the process $proc.ProcessId, I'm getting the dreaded 0x80070005 (E_ACCESSDENIED) error... I am running the PowerShell host as domain admin.
Can anyone please suggest a way that I can get a status on the process I've started, and be able to take an action based on the status?
Thanks!
Update: I guess you are missing remote system credentials:
Try passing the credentials to remote system using -Credential parameter. This takes a PSCredential Object and hence you can do something like:
$cred = Get-Credential
Register-WMIEvent -Credential $cred <and other parameters here>
See if any of the following resolves the access denied error:
0x80070005 (DCOM ACCESS_DENIED)
This error occurs when the connected user is not recognized or is restricted in some fashion by the remote server (for example, the user might be locked out). This happens most often when accounts are in different domains. Recent changes to WMI security can also cause this error to occur:
Blank passwords, formerly permitted, are not allowed in Windows XP and Windows Server 2003.
WMI does not allow asynchronous callbacks to a Windows 98 client. A call like SWbemServices.ExecNotificationQueryAsync from a Windows 98 computer to a Windows XP computer will result in an Access Denied error returned to the Windows 98 machine.
The DCOM configuration access setting might have been changed.
If the target computer is running Windows XP, the Forceguest value under the registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa might be set to force the Guest account off (value is zero).
Source: http://technet.microsoft.com/en-us/library/ee692772.aspx

Powershell Remoting Profiles

How do I use a function in my profile on the remote machine when using Enter-PSSession on my local machine to open a remote PowerShell session.
By JonZ and x0n:
When you use pssessions with the default session configurations, no profile scripts run.
When starting a remote interactive session with Enter-PSSession, a remote profile is loaded. Additionally, only the machine-level profile in $pshome is loaded.
If you want a session to be preconfigured (to load custom functions, snap-ins, modules, etc.), add a profile script to a new sessionconfiguration (for initialize them in the startup script of the remote session configuration).
The Register-PSSessionConfiguration cmdlet creates and registers a new session configuration on the local computer. Use Get-PSSessionConfiguration to view existing session configurations. Both Get-PSSessionConfiguration and Register-PSSessionConfiguration require elevated rights (start PowerShell with the “Run as Administrator” option).
In the target computer, where profile.ps1 contains all your functions:
Register-PSSessionConfiguration -Name WithProfile -StartupScript $PsHome\Profile.ps1
To use this preconfigured session you would type, from the local computer:
Enter-PSSession -ComputerName $computername -ConfigurationName WithProfile
or
Enter-PSSession -ComputerName $computername -ConfigurationName WithProfile -Credential youradminuser#yourtargetdomain
(where $computername is the hostname of the remote server where you registered the pssessionconfiguration).
A good source on PowerShell remoting is the Administrator's Guide to Powershell Remoting.
References:
Powershell Remoting: Use Functions loaded in Powershell remote Profile?
http://jrich523.wordpress.com/2010/07/21/update-creating-a-profile-for-a-remote-session/
Understanding and Using PowerShell Profiles
http://blogs.technet.com/b/heyscriptingguy/archive/2013/01/04/understanding-and-using-powershell-profiles.aspx
About_Profiles (Microsoft Docs)
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles
The six different Windows PowerShell profile paths and use
Current User, Current Host - console
$Home[My ]Documents\WindowsPowerShell\Profile.ps1
Current User, All Hosts
$Home[My ]Documents\Profile.ps1
All Users, Current Host - console
$PsHome\Microsoft.PowerShell_profile.ps1
All Users, All Hosts
$PsHome\Profile.ps1
Current user, Current Host - ISE
$Home[My ]Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1
All users, Current Host - ISE
$PsHome\Microsoft.PowerShellISE_profile.ps1
Windows PowerShell Profiles
http://msdn.microsoft.com/en-us/library/bb613488%28VS.85%29.aspx
This profile applies to all users and all shells.
%windir%\system32\WindowsPowerShell\v1.0\profile.ps1
This profile applies to all users, but only to the Microsoft.PowerShell shell.
%windir%\system32\WindowsPowerShell\v1.0\ Microsoft.PowerShell_profile.ps1
This profile applies only to the current user, but affects all shells.
%UserProfile%\My Documents\WindowsPowerShell\profile.ps1
This profile applies only to the current user and the Microsoft.PowerShell shell.
%UserProfile%\My Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
PowerShell Core Profiles
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles
This profile applies to all users and all hosts.
$env:ProgramFiles\PowerShell\6\profile.ps1
This profile applies to all users, but only to the current host.
$env:ProgramFiles\PowerShell\6\Microsoft.PowerShell_profile.ps1
This profile applies only to the current user, but affects all hosts.
$env:USERPROFILE\Documents\PowerShell\profile.ps1
This profile applies only to the current user and the Microsoft.PowerShell shell.
$env:USERPROFILE\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
Jason,
In my case, I wanted to have my Powershell Profile follow me when I remoted into another computer.
I have created a wrapper function Remote that takes a computername, creates a session, loads your profile into the session, and uses enter-pssession.
Here is the code below:
function Remote($computername){
if(!$Global:credential){
$Global:credential = Get-Credential
}
$session = New-PSSession -ComputerName $computername -Credential $credential
Invoke-Command -FilePath $profile -Session $session
Enter-PSSession -Session $session
}
You could modify the Invoke-Command -FilePath parameter to take any file of your liking.
take a look at this
http://jrich523.wordpress.com/2010/07/08/creating-a-profile-for-a-remote-session/
its a work around for creating a remote profile.
You can't. When starting a remote interactive session with enter-pssession, a remote profile is loaded. Additionally, only the machine-level profile in $pshome is loaded. If you want remote functions available you'll have to initialize them in the startup script of the remote session configuration. Have a look at get/set-pssessionconfiguration on the remote server.
There is another way to use a profile on a remote session:
Copy the chosen profile to the remote server(s) in your documents folder. For example:
Copy-Item -Path $profile.CurrentUserAllHosts -Destination \\computername\C$\Users\MyAccountName\Documents
Enter the PSSession
Enter-PSSession -ComputerName ComputerName
Dot source your profile
. .\Profile.ps1
Drawbacks of this solution:
you must copy once your profile to all the computers where you want to have a profile
you must dot source the profile every time you enter a PSSession
Advantages of this solution:
There is no need of function and you just enter a PSSession like you always do
You do not alter all users' profile by changing the default session configuration
(Thanks to Jeffery Hicks for the tip about the dot sourcing)