How to pass param value to the Invoke-Command cmdlet? - powershell

I wrote a simple powershell script to modify hosts file on remote machines but something goes wrong.
Script:
param(
[string]$value
)
$username = 'username'
$password = 'password'
$hosts = "172.28.30.45","172.28.30.46"
$pass = ConvertTo-SecureString -AsPlainText $password -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $username,$pass
ForEach ($x in $hosts){
echo "Write in $x , value: $value"
Invoke-Command -ComputerName $x -ScriptBlock {Add-Content -Path "C:\Windows\system32\drivers\etc\hosts" -Value $value} -Credential $cred
echo "Finish writing."
}
echo "End of PS script."
When run, it writes a new empty line for each hosts file. This line echo "Write in $x , value: $value" displays $value value.
What I'm doing wrong?

You have to pass the parameter to the scriptblock by defining a param section within your scriptblock and pass the parameters using -ArgumentList :
Invoke-Command -ComputerName $x -ScriptBlock {
param
(
[string]$value
)
Add-Content -Path "C:\Windows\system32\drivers\etc\hosts" -Value $value
} -Credential $cred -ArgumentList $value
Or you leverage the using: variable prefix:
Invoke-Command -ComputerName $x -ScriptBlock {
Add-Content -Path "C:\Windows\system32\drivers\etc\hosts" -Value $using:value
} -Credential $cred

Related

Restart machine using powershell script

I am running the below code but the restart is not working. My intention was to run restart command parallelly on all remote machines at once.
$YourFile = gc "machinelst.txt"
$username = "user1"
$password = "pass1"
$secpw = ConvertTo-SecureString $password -AsPlainText -Force
$cred = New-Object Management.Automation.PSCredential ($username, $secpw)
foreach ($computer in $YourFile)
{
Invoke-Command -ComputerName $computer -credential $cred -ErrorAction Stop -ScriptBlock { Restart-Computer -ComputerName $computer -Force } -AsJob
}
That looks like its the output from Get-Job - could you try Receive-Job $id (Receive-Job 80).
Should give you the actual exception.
This likely runs in parallel just like invoke-command does with an array of computernames:
restart-computer computer01,computer02,computer03,computer04,computer05
Or this. It takes a couple minutes for the winrm service to come back, but they all seem to reboot at the same time.
$c = get-credential
$list = 1..10 | % tostring computer00
restart-computer $list -wait -protocol wsman -cr $c
try this (you will can add -asjob if it's work) :
$username = "yourdomain\user1"
$password = ConvertTo-SecureString "pass1" -AsPlainText -Force
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
get-content "machinelst.txt" | %{
Restart-Computer -ComputerName $_ -Authentication default -Credential $cred
}
if you want use job, you can do it :
$listjob=#()
get-content "machinelst.txt" | %{
$listjob+=Restart-Computer -ComputerName $_ -Authentication default -Credential $cred -AsJob
}
$listjob | Wait-Job -Timeout 30
$listjob | %{
if ($_.State -eq 'Failed' )
{
Receive-Job -Job $_ -Keep
}
}

Read and write from a remote PC to a shared network with powershell

I am trying to read a file from a remote machine, and then what I read, write it in a shared folder in network. This is my code.
Write-Host "Remote copy a file"
$username = 'Usuario'
$password = 'Password'
$myfile = [System.IO.File]::ReadAllBytes("C:\user.txt") ;
$Escribir={[System.IO.File]::WriteAllBytes("\\192.x.x.x\foreach\54.txt", $args)} ;
$pw = ConvertTo-SecureString $password -AsPlainText -Force
$cred = New-Object Management.Automation.PSCredential ($username, $pw)
$servers = Get-Content C:\Users\Agent\Desktop\pcs
foreach($server in $servers) {
$s = New-PSSession -computerName $server -credential $cred
Write-Host "PC name: $server ..." -ForegroundColor GREEN -Background BLACK
$Job = Invoke-Command -Session $s -ArgumentList $myfile -ScriptBlock $Escribir -AsJob
$Null = Wait-Job -Job $Job
Write-Host "Completed"
Remove-PSSession -Session $s
}
When I run the .ps1 file, I get the following error.

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
}

Find the exact matched string from the variable

In the below code, $Result variable has the following information. I need to iterate below each line in $Result variable and get the <APPPOOL NAME> that is, "DefaultAppPool","Classic .NET AppPool" & ".NET v2.0 Classic" as an input to the second Invoke-Command saved in $Result2. Please advise how this can be accomplished.
$Result output:
APPPOOL "DefaultAppPool" (MgdVersion:v4.0,MgdMode:Integrated,state:Started)
APPPOOL "Classic .NET AppPool" (MgdVersion:v2.0,MgdMode:Classic,state:Started)
APPPOOL ".NET v2.0 Classic" (MgdVersion:v2.0,MgdMode:Classic,state:Started)
$Username = '<username>'
$Password = '<Password>'
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username, $pass
$input_file_path = "servers.txt"
$output_path = "result.txt"
foreach ($server in Get-Content $input_file_path) {
$Result = Invoke-Command -ComputerName $server -Credential $Cred -ScriptBlock {
C:\Windows\system32\inetsrv\appcmd.exe list apppools
}
$Result | Add-Content $output_path
$Result2 = Invoke-Command -ComputerName #server -Credential $Cred -ScriptBlock {
C:\Windows\system32\inetsrv\appcmd.exe list apppools <APPPOOL NAME> /text:processmodel.username
}
}

select multiple switch statements

I have the script below that lets me switch between the different elements and runs the functions in them one by one.
But what I need to do now is make it so I can select multiple ones and have them run and pause between them to verifiy if things were loaded correctly. So that way I don't run into the issue having to re rerun the full script again and redo the same one over.
Can anybody show me how to do this? I am lost as to how to get this completed and working properly.
write-host "Sets up location you want to run staging"
$ElementDistro = Read-Host -Prompt "Which Element do you want to run? (TV30/TV30BP/TV30LM/TV30PV/LT101/XR2/MU11/SAP)"
while ($ElementDistro -notmatch "^(TV30|TV30BP|TV30LM|TV30PV|LT101|XR2|MU11|SAP)$")
{
write-host "you have enterd an error" -ForegroundColor Red
write-host "You must type TV30 or TV30BP or TV30LM or TV30PV or LT101 or XR2 or MU11 or SAP"
write-host "you typed $ElementDistro"
write-host "set location you want to run staging"
$ElementDistro = Read-Host -Prompt "Which Element do you want to run? (TV30/TV30BP/TV30LM/TV30PV/LT101/XR2/MU11/SAP)"
}
switch ($ElementDistro)
{
'TV30'
{
# Do TV30 Stuff
write-host "you have entered TC TV30"
$passwd = convertto-securestring -AsPlainText -Force -String ''
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "",$passwd
$session = enter-pssession -computername '' -credential $cred
$source = Select-TC
$destination = 'Desktop'
"Calling Copy-Item with parameters source: '$source', destination: '$destination'."
Copy-Item -Path $source -Destination $destination
exit-pssession
break
}
'TV30BP'
{
# Do TV30BP Stuff
$passwd = convertto-securestring -AsPlainText -Force -String ''
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "",$passwd
$session = enter-pssession -computername '' -credential $cred
$source = Select-TC
$destination = 'Desktop'
"Calling Copy-Item with parameters source: '$source', destination: '$destination'."
Copy-Item -Path $source -Destination $destination
# exit-pssession
break
}
'TV30LM'
{
# Do TV30LM stuff
$passwd = convertto-securestring -AsPlainText -Force -String ''
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "",$passwd
$session = enter-pssession -computername '' -credential $cred
$source = Select-TC
$destination = 'Desktop'
"Calling Copy-Item with parameters source: '$source', destination: '$destination'."
Copy-Item -Path $source -Destination $destination
exit-pssession
break
}
'TV30PV'
{
# Do TV30PV stuff
$passwd = convertto-securestring -AsPlainText -Force -String ''
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "",$passwd
$session = enter-pssession -computername '' -credential $cred
$source = Select-TC
$destination = 'Desktop'
"Calling Copy-Item with parameters source: '$source', destination: '$destination'."
Copy-Item -Path $source -Destination $destination
exit-pssession
break
}
'LT101'
{
# Do LT101 stuff
$passwd = convertto-securestring -AsPlainText -Force -String ''
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "",$passwd
$session = enter-pssession -computername '' -credential $cred
break
}
'XR2'
{
# Do XR2 stuff
$passwd = convertto-securestring -AsPlainText -Force -String ''
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "",$passwd
$session = enter-pssession -computername '' -credential $cred
break
}
'MU11'
{
# Do TF10 stuff
$passwd = convertto-securestring -AsPlainText -Force -String ''
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "",$passwd
$session = enter-pssession -computername '' -credential $cred
break
}
'SAP'
{
# Do SAP stuff
$passwd = convertto-securestring -AsPlainText -Force -String ''
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "",$passwd
$session = enter-pssession -computername '' -credential $cred
break
}
}
break
}
If you got at least V3, you can use Out-GridView with -OutPutMode Multiple as a menu to select multiple items from:
$Menu = 'TV30','TV30BP','TV30LM','TV30PV','LT101','XR2','MU11','SAP','ALL'
$Choices = $Menu | Out-GridView -OutputMode Multiple -Title 'Select Locations you want to run staging, and click OK.'
Switch ($Choices)
{
.....
The quick answer is that Powershell's switch statement accepts an array for input. If you leave out the break statement at the end of each switch case it will execute each case that is a match. Enter your choices as a comma-separated list and put them into an array using the split statement.
Each choice in you $Choices array will be executed. If you put a Pause statement where your break statements are you can pause at the completion of each step.
$Choices = #('TV30','MU11')
switch ($Choices)
{
'TV30' {some code}
'TV30BP' {some code}
'MU11' {some code}
}