powershell threading help using poshrsjob module - multithreading

I am trying to multithread something and ran across this:
http://learn-powershell.net/2015/03/31/introducing-poshrsjob-as-an-alternative-to-powershell-jobs/
Attempting to use but getting errors and not able to access the data I need. Let me explain. I have an extremely simple example here:
#('12.34.56.78')|Start-RSJob -Name {"TEST_$($_)"} -ScriptBlock {
Param($Computername)
Test-Connection -ComputerName $Computername -Quiet
}
get-RSJob|Receive-RSJob
This actually errors saying computername is null. Any type of command I place in here same error comes up saying computername is null. How to get rid of this and how to access the Boolean value that should be returned.
This returns a true or false on the command line but I cannot access this value when run in this script.
Eventually this will need to take an array of IP's and I will need to access all values returned for each machine. I don't have to use this posh module but need threads and thought this a good choice. Any advice here is appreciated.

It looks like you found a bug in my module with using Param() to host the incoming data in the pipeline. Fortunately, you can work around this by just using $_ in the scriptblock.
#('12.34.56.78')|Start-RSJob -Name {"TEST_$($_)"} -ScriptBlock {
Test-Connection -ComputerName $_ -Quiet
}
get-RSJob|Receive-RSJob
That being said, I definitely need to stomp that bug.
Edit: The issue with returning a $False is a bug ($True returns fine) in Receive-RSJob. I'll fix that as well.

Related

Azure Automation Runbook fails triggered with Webhook "Missing argument in parameter list"

I have a fairly simple script placed in Azure Automation Account that Stops Azure Container Instances. I runs smoothly from the portal when I test it or when I just click start button producing no errors and doing the job correctly.
'''
Param
(
[parameter (Mandatory=$false)]
[object]$WebhookData
)
try
{
"Logging in to Azure..."
Connect-AzAccount -Identity
}
catch {
Write-Error -Message $_.Exception
throw $_.Exception
}
$ACIs = Get-AzContainerGroup
foreach ($ACI in $ACIs)
{
Write-Output ("Shutting down the following Azure Container Instance: " + $ACI.Name)
Stop-AzContainerGroup -Name $ACI.Name -ResourceGroupName 'MY_RESOURCE_GROUP_NAME'
Write-Output ("")
}
I created a webhook to start that script. Whenever I sent post request to fire that script it fails with the following error:
'''
ParserError:
Line |
| … .ps1' -WebhookData {WebhookName:XXXX,RequestB …
| ~
| Missing argument in parameter list.
I tried adding sth to message body, sending request from PowerShell and Postman. I am getting response back with JobIds and status code 202. I was looking for similar problem but the only one I got is that one without an aswer.
Any ideas?
The problem was with Powershell version in Azure Automation Runbook. Using Powershell 5.1 solved the problem. It looks like that when Runbook is using Powershell 7.1 it has some formatting problems: link.
It appears the $WebhookData variable contains invalid JSON. The JSON is missing all the double quotes around names and values.
I wrote an ugly regex to "fix" the $WebhookData value, adding back in the missing double quotes. This allows me to pass the string through ConvertFrom-JSON and get a usable object.
I'm sure the regex isn't perfect, but it works for my specific case, so I'm running with it for now.
$Payload = $WebhookData -replace "(?<pre>[\{,])(?<name>[^:]*)", '${pre}"${name}"' -replace ":(?<value>[^\{\},]+)", ':"${value}"' | ConvertFrom-Json

How do I list all active ETW sessions with their output locations, maybe in Powershell?

Question: How can I see all open ETW sessions, including their root paths? I'd expect some PowerShell command like Get-EtwTraceSession, but I don't see any.
Background
I work with EventTracing API, and occasionally find myself out of sessions because of stuff installed on my machine.
This answer tells me I can run logman -ets to see the list of sessions, and then logman stop <SessionName> -ets to stop some sessions. That's good, but how can I know what a cryptically-named session is?
I can tediously query individual sessions, and get a clue from their root path:
> logman -ets SensorFramework-{c4eaa67d-dd9a-4fce-0002-000000000000}
(...)
Root Path: C:\windows\CCM\SensorFramework <<<< Aha! CCM = System Center Configuration Manager
But I'm looking for a more convenient solution.
Solution: Do it through WMI:
Get-WmiObject -Class MSFT_EtwTraceSession -Namespace ROOT/Microsoft/Windows/EventTracingManagement `
| sort -Property LocalFilePath `
| ft -AutoSize -Property Name,LocalFilePath
Note: This only sometimes works (don't know what determines when), and sometimes only shows one session - Circular Kernel Context Logger. When not working, the Get-EtwTraceSession also shows only this session, presumably because it uses the same WMI object underneath.

Powershell script only starts first VM in list

I have an Azure powershell script to start a list of VMs. When it runs it sucessfully starts the first VM in the list then nothing. No errors are reported, it appears to never return from the start command
Code as follows:
$vmList = "VM1", "VM2", "VM3"
Write-Output "Starting VMs in '$($AzureResourceGroup)' resource group";
Foreach ($vm in $vmList)
{
Write-Output "Starting VM...$vm"
$result = Start-AzureRmVM -Name $vm -ResourceGroupName AzureResourceGroup
Write-Output "Result of Start VM...$result"
}
When this run it outputs the "Starting VM....VM1", it starts the VM then nothing...
It sounds like your Start-AzureVM call is simply waiting for the VM to finish starting up.
That is, Start-AzureVm is by default a blocking, synchronous operation - despite its name[1]
To make it asynchronous, use the -AsJob switch, which uses a background job to start the VM; the call ends once that job has been created and returns a job object that you can use to track start-up progress later, via the usual *-Job cmdlets, such as Receive-Job.
[1] Regarding the name Start-AzureVM:
It is a misnomer in that PowerShell's nomenclature calls for the Start verb to exhibit asynchronous behavior:
From https://learn.microsoft.com/en-us/powershell/developer/cmdlet/approved-verbs-for-windows-powershell-commands (emphasis added):
Invoke vs. Start
The Invoke verb is used to perform an operation that is generally a synchronous operation, such as running a command. The Start verb is used to begin an operation that is generally an asynchronous operation, such as starting a process.
Note that the core Start-Sleep cmdlet is similarly misnamed.
With synchronous-by-default behavior, there is no good naming solution, because the name Invoke-AzureVm would be confusing.
The better approach - which would obviously be a breaking change - would have been to make the cmdlet asynchronous by default and offer a -Wait switch for to opt-into synchronous operation.

How to set IIS ApplicationPool "Private Memory Limit" value using PowerShell

I'm using PowerShell for auto-deploying website, and recently found AppPool setting which cannot be set with PS. or at least I did not manage to find out how to do it.
$appPool = $serverManager.ApplicationPools.Add($sitename)...
I need to set "Private Memory Limit" to some value, but it looks like there is no such property at ApplicationPool or ApplicationPoolRecycling object.
Does anybode know workaround for this issue?
This script uses Get-Webconfiguration and Set-WebConfiguration to get the value for private memory for all app pools. You can set each individually or set the application pool defaults for them to inherit. I have commented out the line which actually does the set.
import-module webadministration
$applicationPoolsPath = "/system.applicationHost/applicationPools"
$applicationPools = Get-WebConfiguration $applicationPoolsPath
foreach ($appPool in $applicationPools.Collection)
{
$appPoolPath = "$applicationPoolsPath/add[#name='$($appPool.Name)']"
Get-WebConfiguration "$appPoolPath/recycling/periodicRestart/#privateMemory"
# Set-WebConfiguration "$appPoolPath/recycling/periodicRestart/#privateMemory" -Value 1000
}
I am adding an answer because I was having trouble using the existing.
import-module webadministration
$applicationPools = Get-ChildItem IIS:\AppPools
foreach ($appPool in $applicationPools){
Set-ItemProperty IIS:\AppPools\$appPool.name `
-Name recycling.periodicrestart.privateMemory -Value 7000000
}
Your responses helped me come up with a solution to a problem that I was having with my WSUS servers. I knew that it was the application pool size for the WsusPool that was giving me problems so I made the following PS script and applied it to the root OU for my WSUS servers (I have 3) I was getting a connection error and my option to Reset Server Node didn't help. The event viewer had Event IDs 12002, 12012, 12032, 12022, 12042, 12052, and 12072.
Set-WebConfiguration "/system.applicationHost/applicationPools/add[#name='WsusPool']/recycling/periodicRestart/#privateMemory" -Value 0

PowerShell threading [duplicate]

I am trying to retrieve list of print queues from PowerShell as shown below.
But I am getting
The calling thread cannot access this object because a different thread owns it.
Is it happeneing because PowerShell not being able to support multiple threads?
Is there a way to get around this problem?
As far as I understand, you have to start PowerShell with -STA (single thread appartment) parameter to have your code working :
PowerShell -STA
Add-Type -AssemblyName "system.Printing"
$f = #([system.Printing.EnumeratedPrintQueueTypes]::local, [system.Printing.EnumeratedPrintQueueTypes]::shared)
$ps = New-Object system.Printing.localprintserver
$pq = $ps.GetPrintQueues($f)

Resources