Powershell 3.0 Importing binary module from remote share - powershell

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?

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.

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

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.

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

How to invoke Powershell version 2 on remote computer via Invoke-Command

I'm trying to remotely setup websites on web servers using powershell. The web servers I'm attempting to configure are Windows Server 2008 R2 SP1 which has powershell v2 on it by default.
To make things easier, I'm using the Snapin "WebAdministration".
Whenever I attempt to invoke a the following command:
PS C:\p4\eacp4wireframe\ReleaseEngineering\DL_Powershell\Infrastructure\PowerShell\IIS> Invoke-Command -ComputerName web4 -Credential $admin -ScriptBlock {add-pssnapin WebAdministration; Get-Website}
No snap-ins have been registered for Windows PowerShell version 2.
+ CategoryInfo : InvalidArgument: (WebAdministration:String) [Add-PSSnapin], PSArgumentException
+ FullyQualifiedErrorId : AddPSSnapInRead,Microsoft.PowerShell.Commands.AddPSSnapinCommand
I get the dreaded "No snap-ins have been registered for Windows PowerShell version 2" error.
Logically, I check the version of powershell by running this command:
PS C:\ Invoke-Command -ComputerName web4 -Credential $admin -ScriptBlock {(Get-Host).version}
Major Minor Build Revision PSComputerName
----- ----- ----- -------- --------------
1 0 0 0 web4
I can remotely login to the web server and run the Powershell commands fine.
Any ideas?
That version number is the version number of the host implementation used by remoting e.g.:
C:\PS> Invoke-Command . {Get-Host | Get-Member}
TypeName: System.Management.Automation.Internal.Host.InternalHost
You have to be using at least the PowerShell 2.0 engine because that is when PowerShell Remoting was introduced. It is more likely that you're invoking the 64-bit PowerShell remoting endpoint and you have snapins that either haven't been registered for the 64-bit PowerShell or won't run in 64-bit PowerShell (or vice versa).
If you need to invoke the 32-bit remoting endpoint try this:
C:\PS> Invoke-Command . {[intptr]::size} -ConfigurationName Microsoft.PowerShell32
4

Problem with Remote Powershell ps1 execution

Today I have same issue and I cannot find solution, search in WEB read ton articles but without success.
My problem with running PowerShell script on remote machine.
If I run this script locally – it’s works, but remote not.
This is my full story.
Server:
Windows 2008 R2 with SP1 + latest updates
FW – Off
UAC – ON :
- User Account Control: Use Admin Approval Mode for the built-in Administrator account – Disable
- User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop. – Disable
- User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode – Elevate without prompting
- User Account Control: Detect application installations and prompt for elevation – Disable
Domain: hardening.com
Hostname: qwerty12345
Version of PowerShell is Installed:
PS C:\Windows\system32> $PSVersionTable
Name Value
---- -----
CLRVersion 2.0.50727.5420
BuildVersion 6.1.7601.17514
PSVersion 2.0
WSManStackVersion 2.0
PSCompatibleVersions {1.0, 2.0}
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.1
Client:
Windows 2008 R2 + latest updates
FW – Off
UAC – ON :
- User Account Control: Use Admin Approval Mode for the built-in Administrator account – Disable
- User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop. – Disable
- User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode – Elevate without prompting
- User Account Control: Detect application installations and prompt for elevation – Disable
Domain: systemqa.com
Version of PowerShell is Installed:
PS C:\> $PSVersionTable
Name Value
---- -----
CLRVersion 2.0.50727.4952
BuildVersion 6.1.7600.16385
PSVersion 2.0
WSManStackVersion 2.0
PSCompatibleVersions {1.0, 2.0}
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.1
• On Client installed also PowerCLI
1. On Server , I have file "C:\Windows\Temp\ ConfigurationWinRM.ps1” with following content:
winrm set winrm/config/client `#`{TrustedHosts=`"`*`"`}
winrm set winrm/config/winrs '#{MaxShellsPerUser="100"}'
2. My mission run those script on remote “Server” machine.
3. I run following script from “Client” machine but get always same errors:
Message = Access is denied.
Error number: -2147024891 0x80070005
a. Example 1:
$domainCrd = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "$domainUser#$domainNameFQDN",$domainPASS
$ComputerName = "qwerty12345.hardening.com"
invoke-command -ComputerName $ComputerName -Credential $domainCrd -ScriptBlock {
$FileName = "ConfigurationWinRM.ps1"
$ItemLocation = "C:\Windows\Temp\"
powershell -NoProfile -Command ". $ItemLocation$FileName"
}
b. Example 2:
$ComputerName = "qwerty12345.hardening.com"
$securePassword = ConvertTo-SecureString "**********" -AsPlainText -force
$credential = New-Object System.Management.Automation.PsCredential("$domainName\$domainUser",$securePassword)
Invoke-Command -ComputerName $ComputerName -ScriptBlock {
$FileName = "ConfigurationWinRM.ps1"
$ItemLocation = "C:\Windows\Temp\"
powershell -Command ". $ItemLocation$FileName"
} -Credential $credential
c. Example 3:
[ScriptBlock] $global:runFile = {
$FileName = "ConfigurationWinRM.ps1"
### $ItemLocation = "C:\Windows\Temp\"
$ItemLocation = "$env:windir\Temp\"
& "$ItemLocation$FileName"
}
RemotePowerShellConnect domain $runFile
WSManFault
+ CategoryInfo : NotSpecified: (WSManFault:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Message = Access is denied.
Error number: -2147024891 0x80070005
Access is denied.
WSManFault
Message = Access is denied.
Error number: -2147024891 0x80070005
Access is denied.
[vSphere PowerCLI] C:\> $error[0] | Format-List * -Force
PSMessageDetails :
OriginInfo : qwerty12345.hardening.com
Exception : System.Management.Automation.RemoteException:
Error number: -2147024891 0x80070005
Access is denied.
TargetObject :
CategoryInfo : NotSpecified: (:) [], RemoteException
FullyQualifiedErrorId : NativeCommandErrorMessage
ErrorDetails :
InvocationInfo :
PipelineIterationInfo : {}
d. Example 4:
[vSphere PowerCLI] C:\> [ScriptBlock] $global:www = {
$FileName = "ConfigurationWinRM.ps1"
$ItemLocation = "C:\Windows\Temp\"
function Invoke-Admin() {
param ( [string]$program = $(throw "Please specify a program" ),
[string]$argumentString = "",
[switch]$waitForExit )
$psi = new-object "Diagnostics.ProcessStartInfo"
$psi.FileName = $program
$psi.Arguments = $argumentString
$psi.Verb = "runas"
$proc = [Diagnostics.Process]::Start($psi)
if ( $waitForExit ) {
$proc.WaitForExit();
}
}
Write-Host -ForegroundColor Green "Invoke-Admin powershell $ItemLocation$FileName"
Invoke-Admin powershell $ItemLocation$FileName
}
[vSphere PowerCLI] C:\> RemotePowerShellConnect domain $www
Session state: Opened
Session availability: Available
Running
Service is running ...
You connect to VM Remote PowerShell ...
Invoke-Admin powershell C:\Windows\Temp\ConfigurationWinRM.ps1
[vSphere PowerCLI] C:\>
[vSphere PowerCLI] C:\>
Nothing heppend !!!!! No updates on remote “Server” machine !!!
e. Example 5:
.\tmp\psexec -d \\$hostNAME -u $domainName\$domainUser -p $myPASS cmd /C START /WAIT powershell %windir%\Temp\ConfigurationWinRM.ps1
PsExec v1.98 - Execute processes remotely
Copyright (C) 2001-2010 Mark Russinovich
Sysinternals - www.sysinternals.com
cmd started on qwerty12345 with process ID 3860.
[vSphere PowerCLI] C:\>
Nothing heppend !!!!! No updates on remote “Server” machine !!!
Am I correct in reading that there is just one script file, only on the local server, and not on any of the remote clients?
If that's the case, then I think you should try this syntax:
$FileName = "ConfigurationWinRM.ps1"
$ItemLocation = "C:\Windows\Temp\"
Invoke-Command -ComputerName $ComputerName -filepath "$ItemLocation$FileName" -cred $credential
I think what's happening when you use the scriptblock syntax is:
scriptblock defined on local machine, encapsulated as an object
scriptblock object passed to each remote machine
scriptblock executed verbatim on the remote machine, therefore it's looking for your script file on the remote machine at c:\windows\temp (it doesn't exist so it's throwing some BS access denied error)
Based on the help info the filepath parameter, using -filepath will do the following instead:
read in script file locally, convert
contents to a scriptblock object
scriptblock object passed to each
remote machine
scriptblock executed verbatim on the
remote machine, no references to the
.ps1 file at all at this point