Concurrent Powershell jobs not running command - multithreading

Hey guys first time poster long time reader, I'm having a bit of trouble with my script at the moment and was hoping some would check it out and point out where I've gone wrong, it is as follows:
$Servers = gc "C:\ServerList.txt"
$SB = {
Start-Process {cmd (C:\psexec.exe \\$Server -u username -p password cmd /c "echo.| powershell C:\Autolog.ps1")
}
Foreach ($Server in $Servers)
{
Start-Job -ScriptBlock $SB
}
Essentially what I'm trying to get this script to do is for Every server in "Serverslist.txt" Start a PSEXEC which then initiates an Powershell script on said server
What i'm seeing is that the jobs start but my psexec isn't triggering on the servers and i know that line is good as i've completed isolation testing on that command and manually triggered it
Note: Directories and Credentials remove to maintain privacy

This is likely way more complicated than it needs to be. I would run a scriptblock against that list of computers instead like so:
$cred = New-Object System.Management.Automation.PSCredential ("domain\username",(ConvertTo-SecureString 'password' -asplaintext -force))
foreach ($server in $servers) {
Invoke-Command -ComputerName $comp -ScriptBlock {. C:\Autolog.ps1} -Credential $cred
}

Your job doesn't know what $Server means because jobs run in their own process, and so don't access the parent process' variables. You have to pass the argument. Try this:
Start-Job -ScriptBlock $SB -ArgumentList $Server

Appreciate the help ended up nutting it out and getting it to do what want, the script is as follows:
$Servers = gc "C:\ServerList.txt"
Foreach ($Server in $Servers)
{
[String]$cmd = "& cmd (C:\psexec.exe \\$Server -u Username -p Password cmd /c C:\Autolog.bat)"
[ScriptBlock]$SB = [ScriptBlock]::Create($cmd)
Start-Job -ScriptBlock $SB -ArgumentList $Server
echo "Started Script on $Server"
}
I had to move some of the command out to a .bat because I don't have time to troubleshoot the issue but i'm essentially the C:\Autolog.bat contains "powershell.exe C:\Autolog.ps1" from the first script post

Related

Execute commands in elevation powershell

I am running a Node.JS app that is executing some powershell commands to set the DNS services for my WiFi interface.
Unfortunately, the script fails without admin permissions, so I am trying to elevate the script within node.js
Start-Process -FilePath powershell.exe -ArgumentList {
Write-Host "Hello"
Set-DnsClientServerAddress -InterfaceIndex 10 -ServerAddresses ("127.0.0.1", "8.8.8.8")
sleep 5
} -verb RunAs
For some reason, this isn't applying the changes, despite the script outputting "hello" and waiting for 5 seconds. Does anyone know why that might be?

Trying to use Azure Custom Script Extension to run a background job or a powershell task scheduler

Hi after my vm gets created I run the Azure Custom Script Extension which runs a powershell script. So the script does some basic tasks like create a share create some files and creates a powershell script and stored it on the vm. the last step in the custom vm extension script I have it attempt to setup a task scheduler job to call a powershell script that was created above and the script should end fromt he extension.
The problem isthe extension gets stuck in a running state and never stops. I wrote a log to find out the progress of the script and it shows it went through the whole script fine but it gets stuck in running and the task scheduler script does not run the job.
When i log in the vm manually I ran the script manually and it works fine. So I am not sure what is causing it to hang and what user it is running as the vm extension that is.I tried to run a powershell background job instead of the scheduler and I got the same symptoms above.
The below code is the task scheduler I tried to run the vm custom extension that does not work when trying to set it up through the custom extension but runs fine manually setup from the vm.
$jobname = "MasterFileWatcher"
$script = "c:\test\MasterFileWatcher.ps1"
$repeat = (New-TimeSpan -Minutes 1)
$action = New-ScheduledTaskAction –Execute "$pshome\powershell.exe" -Argument "$script; quit"
$duration = ([timeSpan]::maxvalue)
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).Date -
RepetitionInterval $repeat -RepetitionDuration $duration
$msg = "Enter the username and password that will run the task";
$credential = $Host.UI.PromptForCredential("Task username and
password",$msg,"$env:userdomain\$env:username",$env:userdomain)
$username = $credential.UserName
$password = $credential.GetNetworkCredential().Password
$username = "$env:userdomain\testuser"
$password = "testpass"
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable -DontStopOnIdleEnd
Register-ScheduledTask -TaskName $jobname -Action $action -Trigger $trigger -RunLevel Highest -User $username -Password $password -Settings $settings
I found out the issue.
I had to set the username as system so the task scheduler could run as Localsystem account
Register-ScheduledTask -TaskName $jobname -Action $action -Trigger $trigger -RunLevel Highest -User "System" -Settings $settings

Can I get actual grunt process from Start-Process, not CMD process?

I'm using
Start-Process grunt -ArgumentList 'serve' -PassThru
and add it to an ArrayList. When I view said ArrayList it shows cmd process, not actual node.js process that was launched. If I try to Stop-Process it, quite obviously, kills cmd process, not the running grunt. I can locate running grunt with Get-Process node.
The problem is I need multiple grunts running at the same time and I want a way to distinguish between them somehow. Is there any way I can get actual node process into PowerShell upon initializing it?
This happens because grunt is launched via grunt.cmd which is run by CMD. This file launches grunt in node.
Here is an example of how to find notepad2.exe launched from a CMD similarly to your example:
# start a CMD which starts notepad2 and then waits on it
$process = Start-Process -PassThru 'cmd.exe' '/c "C:\Program Files\Notepad2\Notepad2.exe"'
# Wait for notepad2 to be launched
Start-Sleep -Seconds 2
# find the children of CMD, and kill the one which is notepad2
(Get-CimInstance win32_process -Filter "ParentProcessId='$($process.Id)' AND Name = 'Notepad2.exe'") | %{ Stop-Process -Id $_.ProcessId}
Translating this for grunt:
# start Grunt via grunt.cmd
$process = Start-Process grunt -ArgumentList 'serve' -PassThru
# Wait for node to be launched
Start-Sleep -Seconds 2
# find the children of CMD, and kill the one which is node
(Get-CimInstance win32_process -Filter "ParentProcessId='$($process.Id)' AND Name = 'node.exe'") | %{ Stop-Process -Id $_.ProcessId}
grunt isn't a Win32 executable, it's a javascript file that's run by node.exe. The easiest way to get the instance of node that's running grunt would be to start it yourself:
$ps = start-process -passthru node -argumentlist "$env:APPDATA\npm\node_modules\grunt\bin\grunt"

Powershell Start-Process ignored in remote session

I am starting a new process using:
$removeArguments = "-Command `"&{import-module .\deploy-utility.psm1; RemoveSolutions -solutionNames $solutionNames -url $url;}`""
start-process powershell -ArgumentList $removeArguments -Wait
This works fine when run locally but when run in remote session the statement is simply ignored.
I have also tried moving the command to a separate file but this makes no difference.
$removeArguments = "-File .\deploy-utility-functions.ps1", "remove", "$solutionNames", "$url"
$script = {start-process powershell -ArgumentList $removeArguments -Wait -NoNewWindow | Out-Host}
Invoke-Command -ScriptBlock $script
Remote call:
$script = [scriptblock]::create("& '.\$targetFile' '$arguments'")
$result = Invoke-Command -Session $s -ScriptBlock $script
Any suggestions?
You can have issues with permissions in remote sessions for the second hop ( Permissions of the started process in your case).
See enabling credssp http://ss64.com/ps/enable-wsmancredssp.html

Can I use PowerShell instead of AppCmd.exe to monitor IIS state?

I want to write a script that uses appcmd.exe to monitor IIS state -
restart a site if it's down and/or restart IIS if it's down.
Can this be done with powershell? is there a more natural/easier method of doing this?
Thanks :-)
Windows PowerShell is always the Answer! This should do it for your particular question:
# Cycle IIS if it's not running
Get-Service W3SVC |
Where-Object {$_.Status -ne 'Running' } |
Start-Service
Import-Module WebAdministration
# Cycle websites that are not started
Get-Website |
Where-Object { $_.State -ne 'Started' } |
ForEach-Object { $_.Start() }
Hope this Helps
You can use the WebAdministration module to do it in a more elegant way than using appcmd.
http://technet.microsoft.com/en-us/library/ee790599.aspx

Resources