PowerShell passing arguments to Invoke-Command in a foreach loop - powershell

Why does PowerShell asks me for Credentials to access a remotecomputer, after I already put in the password for my $PW variable and created the correct PSCredentials with it? The other Issue I have is that Start-Process can't find the FilePath specified (Null or empty).
I guess those two errors are because of the same error, it has to be because my Variable-Values aren't passed to the foreach loop. As you can see, I tried to achieve a solution by trying the -argumentlist parameter, but it doesn't work. What Am I doing wrong?
function Install-Exe {
param(
[string[]]$ComputerName,
[string]$UNCexepath,
[string[]]$exeargs
)
$Admin = "domain\admin"
$PW = Read-Host "Enter Password" -AsSecureString
$cred = New-Object System.Management.Automation.PSCredential -argumentlist $Admin, $PW
foreach ($c in $ComputerName) {
Invoke-Command -ComputerName $c -Credential $cred -ArgumentList $cred,$UNCexepath {
Start-Process -Filepath $UNCexepath -Credential $cred -Verb RunAs
}
}}

You need to declare the parameters inside the Invoke-Command scriptblock:
foreach ($c in $ComputerName) {
Invoke-Command -ComputerName $c -Credential $cred -ArgumentList $cred,$UNCexepath {
param($cred,$UNCexepath)
Start-Process -Filepath $UNCexepath -Credential $cred -Verb RunAs
}
}}

Related

Passing Credentials In PowerShell multi line scriptblock

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
}

Run Remote Command via Powershell

I'm trying to invoke discrete CLI commands on a series of remote systems via a script, and I can't get any PowerShell commands to accept them. Rather than try to explain the specifics of the issue, I'll provide some pseudocode of what I'm trying to do below.
Please note that this is just a simple example. Using the stop-service command is not an option. These are explicit commands used via CLI with via the Splunk program that I need to run in this order.
In short, I just can not figure out how to tell PowerShell to run a CLI command verbatim on a remote machine.
foreach ($server in $list)
cd C:\Program Files\SplunkUniversalForwarder\bin
splunk stop
splunk clone-prep-clear-config
splunk start
Bunch of ways you can do this. Using WMI c/o Powershell:
Starting,Stopping and Restarting Remote Services with PowerShell
You can also use Windows remoting, but I'd start here.
You could try...
Foreach($server in $list)
{
Invoke-command -computername $server -scripblock {
$splunkpath = 'c:\program files\splunkuniversalforwarder\bin\splunk.exe'
Start-process -filepath $splunkpath -argumentlist 'stop' -wait -nonewwindow
Start-process -filepath $splunkpath -argumentlist 'clone-prep-clear-config' -wait -nonewwindow
Start-process -filepath $splunkpath -argumentlist 'start' -wait -nonewwindow
}
}
Note: you may need to remove the -wait and/or -nonewwindow from the commands depending on how your process behaves.
There are also output redirection parameters checkout the docs below for more.
Invoke-command
Start-process
I literally just did this this morning. This is the main part I came up with.
foreach($server in $servers){
Write-Host "From " -nonewline; Write-Host "$server" -ForegroundColor Yellow
Invoke-Command -ComputerName $server -ScriptBlock { C:\SplunkUniversalForwarder\bin\splunk.exe stop } -Credential $cred
Invoke-Command -ComputerName $server -ScriptBlock { C:\SplunkUniversalForwarder\bin\splunk.exe clone-prep-clear-config } -Credential $cred
Invoke-Command -ComputerName $server -ScriptBlock { C:\SplunkUniversalForwarder\bin\splunk.exe start } -Credential $cred
}
my full code is below:
#Author: Christopher Boillot
#Clear config of Splunk Forwarder
[CmdletBinding()]
Param ([Parameter(Mandatory=$False,Position=0)]
[String[]]$servers = (Get-Content C:\ClearConfig.txt))
Set-Location $PSScriptRoot
#User login
$User = "user.txt"
$FileExists = Test-Path $User
If ($FileExists -eq $False) {
Write-Host "Enter your user name. This will be saved as $User"
read-host | out-file $User
}
$Pass = "securepass.txt"
$FileExists = Test-Path $Pass
If ($FileExists -eq $False) {
Write-Host "Enter your password. This will be saved as an encrypted sting as $Pass"
read-host -assecurestring | convertfrom-securestring | out-file $Pass
}
$username = cat $User
$password = cat $Pass | convertto-securestring
$cred = new-object -typename System.Management.Automation.PSCredential `
-argumentlist $username, $password
#go through each server in list
foreach($server in $servers){
Write-Host "From " -nonewline; Write-Host "$server" -ForegroundColor Yellow
Invoke-Command -ComputerName $server -ScriptBlock { C:\SplunkUniversalForwarder\bin\splunk.exe stop } -Credential $cred
Invoke-Command -ComputerName $server -ScriptBlock { C:\SplunkUniversalForwarder\bin\splunk.exe clone-prep-clear-config } -Credential $cred
Invoke-Command -ComputerName $server -ScriptBlock { C:\SplunkUniversalForwarder\bin\splunk.exe start } -Credential $cred
}

how to pass command line parameters to invoked session in powershell 2.0

How can i pass command line parameters to a session which is invoked using 'invoke-command' in powershell 2.0
my script:
param(
[string]$hostname = 'my_server_name'
)
function createSession($hostname){
return New-PSSession -ComputerName $hostname -Credential $env:UserDomain\$env:UserName
}
$session = createSession $hostname
invoke-command -Session $session -ScriptBlock {
write-host $hostname
write-host $using:hostname
write-host $script:hostname
write-host '**test text**'
}
Exit-PSSession
Output: (I'm getting empty string if i print the parameter value directly.)
**test text**
use param block
$hostname = $env:computername
Invoke-Command -ScriptBlock { param($hostname)
Write-OutPut $hostname
} -ArgumentList $hostname
param(
[string]$hostname = 'my_server_name'
)
function createSession($hostname){
return New-PSSession -ComputerName $hostname -Credential $env:UserDomain\$env:UserName
}
$session = createSession $hostname
invoke-command -Session $session -ScriptBlock {
$hostname=$using:hostname
or
$hostname=$script:hostname
write-host $hostname
write-host '**test text**'
}
Exit-PSSession
Hope any one of the above helps,If Not Please look at the concept of scoping variables in powershell,May be they will help
Powershell variable scoping

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

Executing powershell remotely issue

Hi when i try to do some code:
$Username = 'us'
$Password = 'password'
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass
powershell.exe -command "Invoke-Command -ComputerName server.com -scriptblock {pathCopyAndUnzip.ps1} -Credential $Cred"
This prompt me for a password but when i try to run this command like here (without powershell.exe):
Invoke-Command -ComputerName server.com -scriptblock {pathCopyAndUnzip.ps1} -Credential $Cred
it works without prompt. Do you know how to resolve that? I need to use option 1 because this command is runned from TFS build definition file like here:
<Exec Command="powershell.exe -command "Invoke-Command -ComputerName $(Server) -scriptblock {path} -Credential $Cred"" Condition="'$(RunTests)' == 'True'"/>
You could put your script into it's own file and then call that from TFS rather inline code.
C:\folder\script.ps1:
Param(
[string]$Username,
[string]$Password,
[string]$OtherParam,
)
$Password = $Password | ConvertTo-SecureString -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$Password
Invoke-Command -ComputerName server.com -FilePath "C:\folder\CopyAndUnzip.ps1 -Something $OtherParam" -Credential $Cred
Then call it like so:
<Exec Command="powershell.exe -command "C:\folder\script.ps1 -username user10 -password P#55w0rd -OtherParam Whatever" Condition="'$(RunTests)' == 'True'"/>
You could try to pipe the commands to powershell.exe like this:
'$Username = "us"; $Password = "password"; $pass = ConvertTo-SecureString -AsPlainText $Password -Force; $Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass; Invoke-Command -ComputerName server.com -scriptblock {pathCopyAndUnzip.ps1} -Credential $Cred' | powershell.exe -command -
<Exec Command="$(PsExecPath) -accepteula \\$(Server) cmd /C powershell -File FILEPATH " Condition="'$(RunTests)' == 'True'"/>
I used old good psExec :) Everything is work now.