Passing Credentials In PowerShell multi line scriptblock - powershell

I have passed credentials before using a credential parameter in my Scriptblock and passing the value via an argument. I expect the size of my Scriptblock to grow so I am using a here string to keep it clean then I convert the string into a Scriptblock. How do I add a credential parameter and argument to my example below. I know the $credential value I use to get my remote session below has the necessary priveleges to get the file I want as I have tested it on the remote machine. So if possible I would like to pass this same credential.
$user = 'MyDomain\username'
$password = ConvertTo-SecureString 'mypassword' -asplaintext -force
$credential = New-Object -typename System.Management.Automation.PSCredential -ArgumentList $user, $password
try {
$s = New-PSSession -ComputerName MyRemoteComputer -Credential $credential
$remoteCommand = #"
New-PSDrive -Name 'P' -PSProvider 'FileSystem' -Root '\\main-server\Folders\DevOps\Projetcs\Juniper'
Get-Item -Path P:\V1.6\InstallFiles\Install.bat
"#
$scriptBlock = [Scriptblock]::Create($remoteCommand)
$status = Invoke-Command -Session $s -ScriptBlock $scriptBlock
Write-Host $status
Exit-PSSession -Session $s
}
catch {
#TODO Add exception handling
}

Related

Need to execute winrm set winrm/config/client '#{TrustedHosts="192.168.4.231"}' command from PowerShell script from remote

I am firing following script from remote machine to add the executer IP (192.168.4.231) in trusted list. but the below script is getting fired but not I am not getting desired results.
Please let me know is there any wrong way I am executing below script.
$servers = #("192.168.4.236")
foreach($server in $servers) {
$username = 'administrator'
$password = '*******'
$pw = ConvertTo-SecureString $password -AsPlainText -Force
$cred = New-Object Management.Automation.PSCredential ($username, $pw)
$s = New-PSSession -ComputerName $server -Credential $cred
Enter-PSSession $s
Invoke-Command -Session $s -Scriptblock {
Invoke-Expression 'winrm set winrm/config/client '#{TrustedHosts="192.168.4.231"}''
}
Write-Host "Completed"
Remove-PSSession $s
}

Passing parameters to Invoke-Command

I'm having issues passing parameters to Invoke-Command, I've tried using -Args and -ArgumentList to no avail.
function One {
$errcode = $args
$username = "Ron"
$password = ConvertTo-SecureString -String "Baxter" -AsPlainText -Force
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
$cred
$Result = Invoke-Command -ComputerName MyPc -ScriptBlock { & cmd.exe /c "C:\Scripts\test.bat" Param1 $errcode ; $lastexitcode} -Credential $cred
echo $result
}
One 10
You can update your function to pass in your parameter as $errcode rather than using $args, this is better code as it's less confusing. (I'd recommend readng up on parameters and functions as it'll certainly help)
Then you need to pass $errcode into Invoke-Command using the ArgumentList parameter, and use $args[0] in its place:
function One ($errcode) {
$username = "Ron"
$password = ConvertTo-SecureString -String "Baxter" -AsPlainText -Force
$cred = New-Object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
$Result = Invoke-Command -ComputerName MyPc -ScriptBlock { & cmd.exe /c "C:\Scripts\test.bat" Param1 $args[0] ; $lastexitcode} -Credential $cred -ArgumentList $errcode
echo $Result
}
One 10

Execute remote PS command properly

I'm trying to change passwords on more than 1000 hosts running windows server 2008/2012. They assigned to different domains, so I connect to them via their IP, all of them have PowerShell remoting open.
Stuck at my script implementation. For now I just want to connect to single host and change the password of the user or admin whatever.
Here is the code I use
$username = "UserWhose Password I want to change"
$password = ConvertTo-SecureString "users old password" -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password
$serverNameOrIp = "host ip address here"
$s = New-PSSession -ComputerName $serverNameOrIp -Authentication default -Credential $cred
#invoke the scriptblock remotely
$sb = {
"[ADSI]`$Admin=`"WinNT://$env:COMPUTERNAME/$env:USERNAME`""
"`$Admin.SetPassword(`"Users new password`")"
}
Invoke-Command -Session $s -ScriptBlock $sb
Remove-PSSession $s
Now, the console output I get:
PS C:\> ./script
[ADSI]$Admin="WinNT://WIN-TA49U0TR9GT/Administrator"
$Admin.SetPassword("Users new password")
PS C:\>
"WinNT://WIN-TA49U0TR9GT/Administrator" belongs to remote host, my local computername and a username are different.
I'm not getting any error or proper output here. The password isn't changing. If I try to run these commands manually on any host - it works.
Any suggestions? Maybe a working solutions?
You define the commands you want to run on the remote host as strings inside a scriptblock. When you invoke the scriptblock on the remote host it does what PowerShell does with all bare strings: echo them.
Remove the outer quoting and escaping and the code should work as you expect:
$sb = {
[ADSI]$Admin = "WinNT://$env:COMPUTERNAME/$env:USERNAME"
$Admin.SetPassword("Users new password")
}
The scriptblock already prevents variables from being expanded in the current context.
Posting complete working script, that accept console arguments, connect to specified host and change the user password.
ARGS = IP USERNAME OLDPASS NEWPASS
Hope this will help somebody
$serverNameOrIp = $args[0]
$username = $args[1]
$password = ConvertTo-SecureString -String $args[2] -AsPlainText -Force
$newPassword = $args[3]
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password
$s = New-PSSession -ComputerName $serverNameOrIp -Authentication default -Credential $cred
$sb = {
param($newPassword)
[ADSI]$Admin = "WinNT://$env:COMPUTERNAME/$env:USERNAME"
$Admin.SetPassword($newPassword)
}
Invoke-Command -Session $s -ScriptBlock $sb -args $newPassword
Remove-PSSession $s

How to return a variable from a remote PowerShell session to a local PowerShell session

I have a PowerShell script that creates a new PowerShell session. I need to return one of the variables from the myriad of variables that is created in this session to the local / calling session. Here is my PowerShell script:
param
(
[string]$user,
[string]$password
)
$secure_password = ConvertTo-SecureString $password -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential $user, $secure_password
$new_session = New-PSSession -Credential $cred
$script = {
$var1 = 0
$var2 = a
}
Invoke-Command -Session $new_session -ScriptBlock $script
Write-Host ($var2)
When the script executes Write-Host ($var2), it doesn't print any value for $var2. How can I return $var2 to the local session?
param
(
[string]$user,
[string]$password
)
$secure_password = ConvertTo-SecureString $password -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential $user, $secure_password
$new_session = New-PSSession -Credential $cred
$script = {
$var1 = 0
$var2 = a
$var2
}
$varFromSession = Invoke-Command -Session $new_session -ScriptBlock $script
Write-Host $varFromSession
Just return the variable from the session's scriptblock, either with Write-Output or return or just use the variable in another command as I've demonstrated. The return value of Invoke-Command will be whatever the scriptblock wrote to the pipeline.

How to use PowerShell to set the time on a remote device?

I want to set the Date and Time of a remote device (Raspberry Pi 2 running Windows IoT) to the value of the Date Time of a local device.
I create a variable $dateTime to hold the local DateTime.
I assign a password to connect to a remote device to a variable $password.
I create a credential object.
I connect to the remote device using Enter-PSSession.
Now that I'm connected I try assigning the remote devices DateTime using Set-Date = $dateTime | Out-String.
I get cannot convertvalue "=" to type "System.TimeSpan" error.
$dateTime = Get-Date
$password = ConvertTo-SecureString "mypassword" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ("myremotedevice \Administrator",$password)
Enter-PSSession -ComputerName myremotedevice -Credential $cred
Set-Date = $dateTime | Out-String
It seems as if the $dateTime variable is out of scope once I am connected via the PSSession. Is there a way around this ?
I wouldn't use Enter-PSSession for this at all, since that's for interactive sessions.
I'd use this:
$dateTime = Get-Date;
$password = ConvertTo-SecureString "mypassword" -AsPlainText -Force;
$cred = New-Object System.Management.Automation.PSCredential ("myremotedevice \Administrator",$password);
Invoke-Command -ComputerName myremotedevice -Credential $cred -ScriptBlock {
Set-Date -Date $using:datetime;
}
Or, if I had multiple things to execute:
$dateTime = Get-Date;
$password = ConvertTo-SecureString "mypassword" -AsPlainText -Force;
$cred = New-Object System.Management.Automation.PSCredential ("myremotedevice \Administrator",$password);
$session = New-PsSession -ComputerName -Credential $cred;
Invoke-Command -Session $session -ScriptBlock {
Set-Date -Date $using:datetime;
}
Invoke-Command -Session $session -ScriptBlock { [...] }
.
.
Disconnect-PsSession -Session $session;
Passing local variables to a remote session usually requires the using namespace.