Powershell error when trying to enter psssession - powershell

I am trying to enter a new PSSession. If I manually run each line it works, but when I run it as part of a script, I get an error. The creds are valid and it seems the session is created, I just cant enter it in the script. The line number referenced is the write-host. Even if I just have an assignment to a variable it errors there.
$cred = New-Object Management.Automation.PSCredential ($username, $pw)
New-PSSession -ComputerName App02 -Credential $cred
Get-PSSession | Enter-PSSession
Write-Host "ERROR: Partial Service Deployment. See error log file(s)"
I get this as an error:
Cannot perform operation because operation "NewNotImplementedException
at offset 63 in file:line:column :0:0 " is not
implemented. At C:\DEV\Sandbox\Sandbox.ps1:29 char:14
+ Write-Host "ERROR: Partial Service Deployment. See error log file(s ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotImplemented: (:) [], RuntimeException
+ FullyQualifiedErrorId : NotImplemented

You can't use Enter-PSSession in a script. Reason: It is intended for interactive purpose. You can use Invoke-Command with the corresponding -Session parameter to perform commands remotely.
See also this thread.
Example of Invoke-Command:
$cred = New-Object Management.Automation.PSCredential ($username, $pw)
$session = New-PSSession -ComputerName App02 -Credential $cred
Invoke-Command -Session $session -ScriptBlock { Get-Service * } #Return all services from the remote machine

Enter-PSSession can only be used interactively. For scripting, use Invoke-Command, and point it at the computer you want to run the command or scriptblock on.

Related

Test-Path Access denied Error - To check if Directory Exists on Shared Drive/Folder using powershell with credentials

I am trying to check if folder exists on network location using Test-Path powershell script with different credential having access to the Network Server but I am getting access denied error. Below is my script which I am trying to execute on local from where I am trying to connect to Network server:
$username="username"
$pass = "#Passw0rd" | ConvertTo-SecureString -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username,$pass
$pathExists = Invoke-Command -ComputerName . -Credential $cred -ScriptBlock {
Test-Path "\\serverName\Folder"
}
Write-Host $pathExists
I am getting below error:
Access is denied
+ CategoryInfo : PermissionDenied: (\serverName\Folder:String) [Test-Path], UnauthorizedAccessException
+ FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShell.Commands.TestPathCommand
+ PSComputerName : localhost
Note: Admin access for the account is given which is used for accessing Network path and directory
Any help will be much appreciated
The issue most likely is because the credentials stored in $cred don't have Admin privileges on your localhost, hence cannot impersonate your invocation.
Here I'm trying something similar to what you're trying, the user stored in $cred is an Administrator on remote host but does not have any permissions on my laptop (I'm obfuscating for obvious reasons):
PS C:\> icm remoteServer -Credential $cred {test-path \\remoteServer\c$\users}
True
PS C:\> icm remoteServer -Credential $cred {test-path \\localhost\c$\users}
True
PS C:\> icm -computername . -Credential $cred {test-path \\localhost\c$\users}
[localhost] Connecting to remote server localhost failed with the following error message : Access is denied. For more
information, see the about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (localhost:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : AccessDenied,PSSessionStateBroken
Edit:
Here is another solution to your problem, Start-Process using the remote credentials and save the results to a file (again obfuscating the name of the remote server):
$argument="-c `"`$path='\\remoteServer\c$\users';'Attempting Test-Path '+`$path;'Result is: '+(Test-Path `$path)`""
$initHash=#{
FilePath='powershell.exe'
Credential=$cred
ArgumentList=$argument
RedirectStandardOutput="$HOME\Documents\testPath.txt"
WindowStyle='Hidden'
}
Start-Process #initHash
PS C:\> gc "$HOME\Documents\testPath.txt"
Attempting Test-Path \\remoteServer\c$\users
Result is: True

How to Install Windows Updates on Remote Computer with PowerShell

I'm trying to install Windows Updates on a Remote Computer with this command:
$InstallSplat = #{
AcceptAll = $true
SendReport = $true
IgnoreReboot = if ($Reboot) { $false } else { $true }
PSWUSettings = #{
SmtpServer = "my mail server"
From = "myfrom <myfrom#myfrom.com>"
To = "myto <myto#myto.com>"
Port = 25
}
}
Invoke-Command -ComputerName $_ -Credential $cred -AsJob -ArgumentList $InstallSplat -ScriptBlock {
param([hashtable]$InstallSplat)
Import-Module PSWindowsUpdate
Install-WindowsUpdate #InstallSplat
$Error | out-file C:\install\installwinupdate.log -Append
}
I pass a credential Object with domain admin privileges in $cred but I still always get this error
Install-WindowsUpdate : Access denied (Ausnahme von HRESULT: 0x80070005 (E_ACCESSDENIED)) In Zeile:4 Zeichen:25
+ Install-WindowsUpdate #InstallSplat
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-WindowsUpdate], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,PSWindowsUpdate.GetWindowsUpdate
The Command Install-WindowsUpdate itself does not have a credential parameter I could use. The Command needs to run in an elevated PowerShell, but I use an elevated PowerShell when starting this command on my Computer.
I Also tried creating a New-PSSession with my $cred and run Invoke-Command -Session $session instead of Invoke-Command -ComputerName $_ with the same result.
Does anybody know what's happening here? Why do I get Access denied?
It can't have anything to do with passing the $InstallSplat because the same thing happens if I don't pass any parameter at all and write the parameters and their Values directly at the command instead of splatting.
The Problem was, that you can't Download or Install Updates on a machine from another remote machine. Here's a list what you can or can't do remotely when it comes to Windows Updates
The solution is, to create a scheduled task on each server you want to install updates from a remote script, and start that task.
luckily, when you use the PSWindowsUpdate module, you don't have to do that yourself, you can just use Invoke-WUJob (formerly Invoke-WUInstall) which does the trick for you.
I used it like so ($ServerData.Value contains a list of my Servers) and it works like a charm. It creates a scheduled task on each server, and runs them immediately, if you add the -RunNow Parameter.
invoke-WUJob -ComputerName $ServerData.Value -Script { Import-Module PSWindowsUpdate ; Install-WindowsUpdate -AcceptAll -SendReport -IgnoreReboot -PSWUSettings #{From='xy';Port=25;SmtpServer='xy';To='xy'} | Out-File C:\install\PSWindowsUpdateLog.txt -Append} -Confirm:$false -verbose -RunNow
Note that what you specify as a script block in -Script will be pasted to -Command " <here> " in your scheduled task, so you should work with ' inside -Script.

Unresolved parameters (Invoke-Command)

When running the code below I get the error message
Invoke-Command : Missing an argument for parameter 'ComputerName'. Specify a
parameter of type 'System.String[]' and try again.
At line:11 char:16
+ Invoke-Command -ComputerName -ScriptBlock $scriptblock -Credential $Cred -Argum ...
+ ~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-Command],
ParameterBindingException
+ FullyQualifiedErrorId : MissingArgument,Microsoft.PowerShell.Commands.InvokeCommandCommand
The code:
$item = "1337"
$username = "username"
$password = "password"
$Cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, ($password | ConvertTo-SecureString -AsPlainText -Force)
$scriptblock = {
New-PSDrive -Name SampleDC -PSProvider FileSystem -Root \\sampleDC\scripts
."C:\scripts\sample.ps1" # include global functions scripts
new_user $args[0] # new_user is a function in global functions
}
Invoke-Command -ScriptBlock $scriptblock -Credential $Cred -ArgumentList $item
You cannot run Invoke-Command with different credentials without specifying a computer. The error you're getting is because you used the parameter -ComputerName without an argument.
To have Invoke-Command run the scriptblock on the local computer use either of the following commands:
Invoke-Command -Computer . -ScriptBlock $scriptblock -Credential $Cred ...
Invoke-Command -Computer localhost -ScriptBlock $scriptblock -Credential $Cred ...
Invoke-Command -Computer $env:COMPUTERNAME -ScriptBlock $scriptblock -Credential $Cred ...
Note that if the user whose credentials you're passing does not have admin privileges you'll be getting an error like this:
[localhost] Connecting to remote server localhost failed with the following
error message : Access is denied. For more information, see the
about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (localhost:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : AccessDenied,PSSessionStateBroken
In that case you need to enable PowerShell Remoting for them first. Run the following command in an elevated PowerShell console and add the user or group in the dialog that pops up.
Set-PSSessionConfiguration Microsoft.PowerShell -ShowSecurityDescriptorUI
From the documentation:
HOW TO ENABLE REMOTING FOR NON-ADMINISTRATIVE USERS
ERROR: ACCESS IS DENIED
To establish a PSSession or run a command on a remote computer, the user must have permission to use the session configurations on the remote computer.
By default, only members of the Administrators group on a computer have permission to use the default session configurations. Therefore, only members of the Administrators group can connect to the computer remotely.
To allow other users to connect to the local computer, give the user Execute permissions to the default session configurations on the local computer.
The following command opens a property sheet that lets you change the security descriptor of the default Microsoft.PowerShell session configuration on the local computer.
Set-PSSessionConfiguration Microsoft.PowerShell -ShowSecurityDescriptorUI
The computername parameter is missing. I believe you need to be at an elevated prompt to invoke-command on localhost.

PSCredential variable stops working for WinRM function after being passed to get-winevent

I am seeing WinRM Client errors when reusing a Credential object, but only if I'm using it on Get-WinEvent, before I used it on Get-WindowsFeature.
If I replace the Get-WindowsFeature with an Invoke-Command calling Get-WindowsFeature against the server and using the same credentials object then things work as expected, but that causes other issues with different parts of my script, and I'd rather understand why it's not working.
I've stripped things down to the bare minimum to demonstrate the error and got to this.
$Cred = Get-Credential
$Name = "server01"
Get-WindowsFeature -ComputerName $Name -Credential $Cred
Get-winEvent -ComputerName $Name -Credential $Cred -MaxEvents 1
Get-WindowsFeature -ComputerName $Name -Credential $Cred
Expected Results
List of Windows features and their status on server01
The most recent event log entry on server01
List of Windows features and their status of server01
Actual Results
List of Windows features and their status on server01
The most recent event log entry on server01
Get-WindowsFeature : The WinRM client cannot process the request. Requests must include user name and password when Basic or Digest authentication mechanism is used. Add the
user name and password or change the authentication mechanism and try the request again.
At line:1 char:1
+ Get-WindowsFeature -ComputerName $Name -Credential $Cred
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-WindowsFeature], CimException
+ FullyQualifiedErrorId : Microsoft.Management.Infrastructure.CimException,Microsoft.Windows.ServerManager.Commands.GetWindowsFeatureCommand
why not try this instead
$Cred = Get-Credential
$Name = "server01"
invoke-command -ComputerName $Name -Credential $Cred -ScriptBlock {
Get-WindowsFeature
Get-winEvent -MaxEvents 1
Get-WindowsFeature
}

Invoking-Command for Exchange in Powershell - block is not allowed in a Data section

What I'm trying to do is run this script:
$WPFcmdCreateNewUser.Add_Click({
$ScriptBlockContent = {
param ($first,
$last,
$upn,
$ou,
$password
)
$encryptedpass = ConvertTo-SecureString -AsPlainText $password -Force
New-RemoteMailbox -Name $name -OnPremisesOrganizationalUnit $ou -UserPrincipalName $upn -FirstName $first -LastName $last -Password $encryptedpass -ResetPasswordOnNextLogon $false
}
$ex = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://SERVERNAME/PowerShell/
Invoke-Command -Session $ex -ScriptBlock $ScriptBlockContent -ArgumentList ($WPFtxtNewFirstName.Text, $WPFtxtNewLastName.Text, $WPFtxtNewAlias.Text, $WPFcboNewOU.SelectedItem.Content, $WPFtxtNewPassword.Text)
})
But it's giving me the error:
ERROR: A Begin statement block, Process statement block, or parameter statement is not allowed in a Data section.
ERROR: + CategoryInfo : ParserError: (:) [], ParseException
ERROR: + FullyQualifiedErrorId : InvalidScriptBlockInDataSection
ERROR: + PSComputerName : SERVERNAME
I'm running the whole command from a button click in a XAML Powershell GUI. I googled alot trying to solve the problem as I usually do but no luck :(
Any help would be GREATLY appreciated.
It looks like Exchange uses restricted language mode for remote sessions and you can't execute scriptblocks in your session.
As a security feature, the language mode is obviously controlled at
the server (Exchange), so if you want to enable execution of
scriptblocks you need to interactively logon (RDP or console) to
Exchange and create a new session configuration via
Register-PSSessionConfiguration. You may then connect to Exchange
using this session configuration via New-PSSession -ConfigurationName
and you will then be able to execute scriptblocks by passing this
session instance to Invoke-Command -Session.
Reference:
Remote powershell scriptblock execution question
Bit of an old bump here, but seeing as it is rather high on Google search I figured I could add how I fixed this issue:
$DomainCredential = (Get-Credential)
$fqdn = "<The fully qualified domain name of the target server>"
#Creates a session to the Exchange Remote Management Shell so that we can run Exchange commands. Use https:// if you have a proper setup with certificates. ( Mine was in test env )
$ConfigSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$fqdn/powershell `
-Credential $DomainCredential -Authentication Kerberos
#Imports the module that exists in the session, in this case, Exchange Management -AllowClobber gives the imported commands presedence.
Import-Module (Import-PSSession $ConfigSession -AllowClobber)
This imports the Exchange Commands as you would in a local session. The Exchange commands will still be executed on the remote server. Remember to close the session when done.