OK, I’m piggybacking off my previous question Powershell script to get IIS app pool recycling time from servers and wondering what I’m doing wrong
I have a list of IIS app pools (apppools.txt) and a list of servers (servers.txt)
When I run it as written below, the only output I get is the FIRST app pool from the list for each node. Can anybody help me find my (probably very simple) mistake?
Output example:
“ServerName”,”AppPool”,”RecycleTime”
“serverS26″,”Pool1″,”04:10:00”
“serverS27″,”Pool1″,”04:10:00”
When I would expect to get about 10 app pools and their respective recycling times. I’m sure it’s something stupid with my ICM Params or arguments.
$apppools =gc c:tempapppools.txt
$servers = Get-Content C:tempservers.txt
foreach ($server in $servers){
Invoke-Command -ComputerName $server -argumentlist @($apppools) -scriptblock {
param($apppools)
$servername = hostname
$infoObject = New-Object PSObject
import-module webadministration
foreach ($a in $apppools){
$recycle = (Get-ItemProperty -Path "IIS:AppPools$a" -Name recycling.periodicRestart.schedule.collection).value.tostring()}
Add-Member -inputObject $infoObject -memberType NoteProperty -name "ServerName" -value $Servername
Add-Member -inputObject $infoObject -memberType NoteProperty -name "AppPool" -value $a
Add-Member -inputObject $infoObject -memberType NoteProperty -name "RecycleTime" -value $recycle
$infoObject
} | Select-Object * -ExcludeProperty PSComputerName, RunspaceId, PSShowComputerName | Export-Csv -append -path "C:temprecycling.csv" -NoTypeInformation
}
4
I suspect your parameters to Invoke-Request
are getting splatted. Basically you need to be more explicit defining variable types to avoid these types of issues. When running Invoke-Command
on a remote system your single array of strings variable is interpreted as multiple positional variables being passed to the script block. As your only defining a single named argument param($apppools)
in your script block your only seeing the 1st value in the original array.
I’ve made a few changes to your code below that i think should solve your issue:
- Forcing
$apppools
to be of type[string[]]
(instead of Object[]). - Specifying the type of the value passed to
-ArgumentList
– Using([Object[]] @(,$apppools))
instead of@($apppools)
ensures you pass an[Object[]]
ie an object array with 1 element. And that element is your array of app pool name strings (of type [string[]]). - Ive set the type of
$apppools
inside the script block to[String[]]
GC
isGet-Content
so updated for consistency only. The type of$servers
doesnt really matter as that doesn’t get passed to your script block, but again updated for consistency.
[string[]] $apppools = Get-Content c:tempapppools.txt
[string[]] $servers = Get-Content C:tempservers.txt
foreach ($server in $servers){
Invoke-Command -ComputerName $server -ArgumentList ([Object[]] @(,$apppools)) -ScriptBlock {
param([String[]] $apppools)
(im not sure if only #2 might actually be required, but the rest is good practice to avoid weird issues with type conversion 🙂
As a side note, if you litter your code with write-host
‘s, you can get any variables type, and if its an array, you can get its length like this:
Write-Host $apppools.GetType()
Write-Host $apppools.Length
I think to get any output from the script block you would need to include Start-Transcript -Path $logfilepath
at the start of the block. The path/filename in $logfilepath
will be created on the remote computer though.
3