Invoke-Command on remote target with specific Powershell Version possible? - powershell

I'm trying to write a small PowerShell script which will use a specific PowerShell module on a remote machine to do some things. This module requires the use of a PowerShell Version >= to work.
I tried using Invoke-Command to execute the script on the remote machine, but I can't figure out how to use the latest PowerShell Version available on the remote target:
$SessionOption = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
$Session = New-PSSession -ComputerName "TARGETHOST" -Authentication Negotiate -SessionOption $SessionOption
Invoke-Command -Session $Session -ScriptBlock {
(Get-Host).Version
}
Will result in Version 1 used. After some tinkering I found a way to do what I want:
$SessionOption = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
$Session = New-PSSession -ComputerName "TARGETHOST" -Authentication Negotiate -SessionOption $SessionOption
Invoke-Command -Session $Session -ScriptBlock{
C:\Windows\System32\WindowsPowerShell\v1.0\Powershell.exe -Command {
(Get-Host).Version
}
}
But I don't think this is a nice solution, because I'm spawning another PS session inside the remote session. Now I'm wondering if there are nicer ways to accomplish the same thing.

Back when PowerShell was created, the original idea was that the version would be differentiated by script extension.
That idea was not implemented to preserve backward compatibility and to avoid confusion, so now only have .ps1 files (and not .ps2, .ps3, etc.).
As backwards compatibility was preserved, they didn't need to keep old versions of powershell around either, and so PowerShell v2 installed into the C:\Windows\System32\WindowsPowerShell\v1.0 directory... over the top of the original v1.0 and keeping the same directory name.
So even though you think you are running the PS v1 from that directory, you are actually running the latest Powershell version. You can confirm this by running powershell.exe from that location and checking version with $PSVersionTable
In my case:
PS C:\> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.15063.608
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.15063.608
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1

I had the same issue with my Invoke-Command script, it would return version 1.0.0.0 when checking with (Get-Host).Version as well as $host.version. However $PSVersionTable.PSVersion successfully output 5.1. So I modified the script that is asking for the version to use $PSVersionTable.PSVersion and now it runs without complaining.

Related

I have 8 brief scripts to restart PCs in diff rooms. One abruptly stopped. No changes have fixed it

This script works fine:
$machines = get-content H:\0PS\Restart\Inventory417.txt
restart-computer -computername $machines -force
This script DID work fine until this week. I made no changes prior to the failure:
$machines = get-content H:\0PS\Restart\InventoryAccom.txt
restart-computer -computername $machines -force
With the omission of the '417' in the first one and the 'Accom' in the second, there are 100 additional characters in each and they both LOOK identical to me.
Can someone see what I'm missing? The info re: the Powershell version is;
Name Value
---- -----
PSVersion 5.1.14409.1018
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14409.1018
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
Thanks very much!
I've copied working scripts and merely substituted the name of the inventory file and tried running that. The same failure occurred.
The results for about three years is that the PCs either restarted or reported the PC ID that failed. All of the scripts except for the one indicated above still do so.
None of the scripts have ever returned a list of anything UNLESS there are devices that fail to restart - then those devices are listed.
When I run the script, the following is returned immediately:
PS C:\Windows\system32> $machines = get-content H:\0PS\Restart\InventoryAccom.txt
restart-computer -computername $machines -force
Restart-Computer : Cannot validate argument on parameter 'ComputerName'. The argument is null or
empty. Provide an argument that is not null or empty, and then try the command again.
At line:2 char:32
+ restart-computer -computername $machines -force
+ ~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Restart-Computer], ParameterBindingValidationExcep
tion
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.Resta
rtComputerCommand
PS C:\Windows\system32>
Sorry. Forgot to mention that I CAN shut them down via shutdown /i.

Export O365 users with licences, company, job title etc

i need to export users with several infos, like upn, licence used, company, city.
in each scripts available on internet get-user is used, but i have always the same error in powershell => get-user is not recognized...
i seached, import-module etc. but always the same error, somebody can help me ?
Context:
. windows 10 up to date
. Powershell run in admin
. PS C:\WINDOWS\system32> $psversiontable
Name Value
---- -----
PSVersion 5.1.17134.228
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.17134.228
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1'
. PS C:\WINDOWS\system32> get-module
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Binary 2.0.1.16 AzureAD {Add-AzureADApplicationOwner, Add-AzureADDeviceRegisteredO...
Manifest 3.1.0.0 Microsoft.PowerShell.Management {Add-Computer, Add-Content, Checkpoint-Computer, Clear-Con...
Manifest 3.1.0.0 Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Manifest 1.1.183.17 MSOnline {Add-MsolAdministrativeUnitMember, Add-MsolForeignGroupToR...
Binary 1.0.0.1 PackageManagement {Find-Package, Find-PackageProvider, Get-Package, Get-Pack...
Script 1.0.0.1 PowerShellGet {Find-Command, Find-DscResource, Find-Module, Find-RoleCap...
Script 1.2 PSReadline {Get-PSReadlineKeyHandler, Get-PSReadlineOption, Remove-PS...
Thx a lot, actually I was missing out the part about PS ExchangeOnline...
So the answer is just:
$exchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential $credential -Authentication "Basic" -AllowRedirection
Import-PSSession $exchangeSession
and get-user is working :)
thx again

Run remote Powershell session as version 2

I'm on a server that is running Powershell Version 2:
PS C:\> $PSVersionTable
Name Value
---- -----
...
PSVersion 2.0
I then create a new remote session to a different computer and connect to it:
$sess = New-PSSession -ComputerName {ComputerName} -Credential $credential
It returns me the result:
PS C:\> Invoke-Command -Session $sess -ScriptBlock { $PSVersionTable }
Name Value
---- -----
...
PSVersion 3.0
However, I need Powershell to be in Version 2 for my script so I enter a session (to make it easier). I then try to get Powershell to be Version 2:
C:\> Enter-PSSession -Session $sess
[{ComputerName}]: PS C:\> Powershell -Version 2
Windows Powershell
Copyright (C) 2009 Microsoft Corporation. All rights reserverd
And then it just hangs (or at least never lets me enter anything else into the console until I Ctrl-C).
I've also tried going through the Invoke-Command:
PS C:\> Invoke-Command -Session $sess -ScriptBlock { Powershell -version 2 }
and it does the same.
I've also tried to register a PSSessionConfiguration as per here: https://technet.microsoft.com/en-us/library/hh847899.aspx
PS C:\> Register-PSSessionConfiguration -Name PS2 -PSVersion 2.0
But I get:
Register-PSSessionConfiguration: a parameter cannot be found that matches parameter name 'PSVersion'.
Does anyone have any ideas of what I can try next?!
Thanks
On what machine did you run Register-PSSessionConfiguration?. Your computer or the "server"?
You need to make the configuration on the target server. That is what you will be running the hosted PSSessionConfiguration.
I just tried the steps in the technet article and it worked perfectly. My 2008 server remoted to my windows 7 machine running a 2.0 PSSessionConfiguration.
On target server/host:
Register-PSSessionConfiguration -Name PS2 -PSVersion 2.0
Then, on the client machine, reference the 'PS2' configuration.
$s = New-PSSession -ComputerName Server01 -ConfigurationName PS2
I take it that the following doesn't work either:
#Requires -version 2.0
Another kluge you could try is to create a scheduled task on the target and have the task fire off your script with Powershell.exe -version 2

Powershell 3.0 Importing binary module from remote share

There are two machines in this scenerio:
client.sub.domain.com (client machine PSRemoting to remote server)
server.sub.domain.com (remote server that client is PSremoting into)
I am using the below commands to start a psremote session using CredSSP to do "second-hop" authentication:
$session = New-PSSession -cn server.sub.domain.com -Credential $credential -Authentication Credssp
Invoke-Command -Session $session -ScriptBlock {. '\\client\Profile\Microsoft.PowerShell_profile.ps1'}
Invoke-Command -Session $session -ScriptBlock { Import-Module \\client\Profile\Modules\Posh-SSH }
Last line above produces the error below (this error happens with any binary module I use). I need this damn error to go away!
Could not load file or assembly 'file://\client\Profile\Modules\Posh-SSH\Assembly\Renci.SshNet.dll' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515) + CategoryInfo : validOperation: (:) [Import-Module], FileLoadException
Below are all things I've tried/verified:
On server.sub.domain.com:
PS C:\Users\MKANET\Desktop\Dev>Get-WSManCredSSP
The machine is not configured to allow delegating fresh credentials.
This computer IS CONFIGURED to receive credentials from a remote client computer.
On client.sub.domain.com:
PS C:\Users\MKANET\Desktop\Dev>Get-WSManCredSSP
The machine IS CONFIGURED to allow delegating fresh credentials to the following target(s): wsman/*.sub.domain.com
This computer is not configured to receive credentials from a remote client computer.
I put below in $PSHome\Powershell.exe.config on Client
<?xml version="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0.30319"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
<runtime>
<loadFromRemoteSources enabled="true"/>
</runtime>
</configuration>
On Client: (I tried running the below commands, since nothing else worked. Needless to say, this didn’t help any.)
Set-Alias CasPol "$([Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory())CasPol.exe"
CasPol -pp off -machine -addgroup 1.2 -url file://\S858018\Profile\Modules\* FullTrust
On both client and server:
PS C:\Users\MKANET\Desktop\Dev>$psversiontable
Name Value
---- -----
WSManStackVersion 3.0
PSCompatibleVersions {1.0, 2.0, 3.0}
SerializationVersion 1.1.0.1
BuildVersion 6.2.9200.16398
PSVersion 3.0
CLRVersion 4.0.30319.1008
PSRemotingProtocolVersion 2.2
The process that is receiving the invoke-command on the remote machine is not powershell.exe, but wsmprovhost.exe. You would need to change the config file of that process like you did for powershell.exe if you want it to have any effect.
Fusion log can be of use when debugging assembly loading problems. Be sure to do this on your remote machine since that is where the assembly loading takes place.
Also have you tried the caspol thing on the remote machine?

How to load Powershell ISE 3 with powershell v2 inside?

I just installed new powershell 3 on my Windows 7 machine and than I found out that new version of powershell doesn't work with Sharepoint 2010.
I also found a solution for this problem (here or here). But it only solves the problem for the standart powershell console. As we do most of the work through ISE, I wonder if it is possible to do the same thing in ISE?
I tried to add Version parameter, but ISE doesn't know it. I tried to type powershell -version 2 into ISE's console, but it didn't help.
If it would not be possible, I have another question: I need to use ISE with Sharepoint 2010, so how can I uninstall powershell 3 and new ISE?
This is a known issue when the Windows Management Framework 3.0 update is installed (it inlcudes PS 3.0) which, as it uses .net 4.0 makes all the SP2010 cmdlets (which are 3.5), incompatible.
The console application can accept the "-version 2" switch, but as pointed out this is not compatible with the ISE.
It is a known issue, another article suggests uninstalling the WMF update and re-booting the server, which I think is the only real answer to the last part of your question.
You can do this by creating new PSSession.
Register-PSSessionConfiguration -Name PS2 -PSVersion 2.0 –ShowSecurityDescriptorUI
# Please consult system admin when your run set-item and Enable-WSManCredSSP command
Set-Item wsman:localhost\client\trustedhosts -value * -Confirm:$false -Force
Enable-WSManCredSSP -Role Client –DelegateComputer * -Force
Enable-WSManCredSSP -Role Server -Force
# For test purpose
# Get-WSManCredSSP
# get-item wsman:localhost\client\trustedhosts
$cred = Get-Credential
$session = New-PSSession -ComputerName $env:COMPUTERNAME -authentication credssp -ConfigurationName PS2 -Credential $cred
Enter-PSSession $session
# 2.0 runtime
Add-PSSnapin microsoft.sharepoint.powershell
$web = Get-SPWeb http://SPSite/
$web.Url
Exit-PSSession
Unregister-PSSessionConfiguration -Name PS2
Disable-WSManCredSSP -Role Client
Disable-WSManCredSSP -Role Server
If you don't exit PSSession, you can run 2.0 runtime command from Powershell ISE 3.