Restart machine using powershell script - powershell

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
}
}

Related

Invoke-Command does not kill process on remote machine

Before deployment, I'm trying to kill processes that lock files using PowerShell Invoke-Command
This is my code:
$password = ConvertTo-SecureString "password" -AsPlainText -Force
$credentials = New-Object System.Management.Automation.PsCredential("Admin",$password)
$scriptBlock = {Get-Process | Where-Object { $_.MainWindowTitle -like 'MyApp*'} | Stop-Process}
Invoke-Command -computername Agent1 -Credential $credentials -scriptblock $scriptBlock
Unfortunately it does not do anything and no errors are thrown.
On the machine, this works fine:
Get-Process | Where-Object { $_.MainWindowTitle -like 'MyApp*'} | Stop-Process
As described above create a PS session object:
$ErrorActionPreference = "Stop"
$password = ConvertTo-SecureString "password" -AsPlainText -Force
$credentials = New-Object System.Management.Automation.PsCredential("Admin",$password)
$scriptBlock = {
$process = Get-Process
$process | Where-Object { $_.MainWindowTitle -like 'MyApp*'} | Stop-Process}
$process
}
$session = New-PsSession -ComputerName "Agent1" -Credentials $credentials
$remoteProcess = Invoke-Command -Session $session -Credential $credentials -scriptblock $scriptBlock
$remoteProcess | format-table
Above code will also return you a list processes running on the remote host. Based on $remoteProcess you'll see if the process to kill was running or not. I also set the ErrorActionPreference to stop which forces above code to stop on the first error (in case of the session could not be created).
Hope that helps

Invoke-Command with remote session: Cannot validate argument on parameter

I wrote a script to restart a few ASP.NET websites on a remote server:
$computerName = #...
$password = #...
$secureStringPassword = ConvertTo-SecureString -AsPlainText -Force -String $password
$userName = #...
$credential= New-Object System.Management.Automation.PSCredential ($userName, $secureStringPassword)
$websiteNames = #..., #..., #...
Get-PSSession -ComputerName $computerName -Credential $credential | Remove-PSSession
$psSession = New-PSSession -ComputerName $computerName -Credential $credential
Invoke-Command -Session $psSession -ScriptBlock { $websiteNames | foreach{ Stop-Website -Name $_ } }
Invoke-Command -Session $psSession -ScriptBlock { $websiteNames | foreach{ Start-Website -Name $_ } }
$psSession | Remove-PSSession
For some reasons my Invoke-Command do not run properly, I have the following error message:
Cannot validate argument on parameter 'Name'. The argument is null. Provide a valid value for the argument, and then try running the command again.
When the commands are run after an Enter-PSSession it works fine within a -ScriptBlock it kinda mess up the -Name parameter, any idea how to fix that up?
The remote session cannot access the variables you have defined locally. They can be referenced with $using:variable
Invoke-Command -Session $psSession -ScriptBlock { $using:websiteNames | foreach{ Stop-Website -Name $_ } }
Invoke-Command -Session $psSession -ScriptBlock { $using:websiteNames | foreach{ Start-Website -Name $_ } }
More information in the about_remote_variables help:
get-help about_remote_variables -Full
Actually just needed to pass the arguments to the -ArgumentList of the -ScriptBlock and use $args to reference to it within the function block:
Invoke-Command -Session $psSession -ScriptBlock { $args | foreach{ Stop-Website -Name $_ } } -ArgumentList $websiteNames
Invoke-Command -Session $psSession -ScriptBlock { $args | foreach{ Start-Website -Name $_ } } -ArgumentList $websiteNames

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.

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
}
}

Enter PSSession with Variable for ComputerName

I am trying to enter a PSSession using -Computername $Server which was previously defined, but I can't seem to get this to work.
I have tried single, double, and no quotes around the variable at all. What am I doing wrong?
$Servers = Import-Csv "C:\Users\username\Desktop\DNS.csv"
$secpass = ConvertTo-SecureString 'mypassword' -AsPlainText -Force
$myCred = New-Object System.Management.Automation.PSCredential("username", $secpass)
foreach ($Object in $Servers) {
$Server = $Object.Name
Enter-PSSession -ComputerName "$Server" -Credential $myCred
sl HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters
Invoke-Command -ScriptBlock {Get-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters}
Exit-PSSession
}
We use enter pssession for creating an interactive session with the remote computer.
In your case, you do not need to have an interaction with the remote system. You just need to fetch the details from the remote systems which are present in the csv file.
So, Instead of this:
foreach($Object in $Servers) {
$Server = $Object.Name
Enter-PSSession -ComputerName "$Server" -Credential $myCred
sl HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters
Invoke-Command -ScriptBlock {Get-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters}
Exit-PSSession
}
Do This:
foreach($Object in $Servers)
{
$Server = $Object.Name
Invoke-Command -ComputerName $Server -ScriptBlock {Get-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters} -Credential $myCred
}
Note: I believe you have enabled PSRemoting and have edited trusted hosts.
The ComputerName param of Invoke-Command will accept an array of servers so you can do away with the foreach loop entirely and simplify your code to:
$Servers = Import-Csv "C:\Users\username\Desktop\DNS.csv" | Select-Object -ExpandProperty Name
$secpass = ConvertTo-SecureString 'mypassword' -AsPlainText -Force
$myCred = New-Object System.Management.Automation.PSCredential("username", $secpass)
Invoke-Command -ComputerName $Servers -ScriptBlock {Get-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters} -Credential $myCred