Simon Bruun
Simon Bruun

Reputation: 87

Using ForEach-Object on Array of Structs - Powershell

I'm evolving my Surveillance script, so i can choose a Service/Maintenance Window. Where all errors are ignored between two time intervals.

This is what i got:

Add-Type -TypeDefinition @"
public struct ServiceWindow
{
    public int SWStart;
    public int SWEnd;
}
"@

[array]$SWArray = New-Object ServiceWindow
$time = Get-Date -Format HHMM
$time

$ActiveBatchVar = "1000-1005;1306-1345;2300-2305"

$ActiveBatchVar = $ActiveBatchVar.Split(";")

For ($i = 0; $i -lt $ActiveBatchVar.Length; $i++) 
{
    $tempSW = New-Object ServiceWindow
    $tempSW.SWStart = $ActiveBatchVar[$i].Split("-")[0]
    $tempSW.SWEnd = $ActiveBatchVar[$i].Split("-")[1]

    If ($i -eq 0) { $SWArray = $tempSW } else { $SWArray += $tempSW }
}
Write-Host Complete array...
$SWArray

ForEach-Object ($SWArray) {
Get-Date -Format HHMM

If ($time -ge $_.SWStart -and $time -lt $_.SWEnd) {Write-Host Wohoo we have hit a service window service window...}
}  

I get an error in my last ForEach-Object loop. and can't figure out what is wrong.

The point is that I would like to check if the current time is between two given times, like "1000-1005".

Anyone got a clue what’s missing, or maybe a way to simplify the whole thing ;)

Upvotes: 1

Views: 1740

Answers (4)

Jamie Bilinski
Jamie Bilinski

Reputation: 1

if you have a small array...

($SWArray).foreach({
Get-Date -Format HHMM
If ($time -ge $_.SWStart -and $time -lt $_.SWEnd) 
 {Write-Host Wohoo we have hit a service window service window...}
})

Upvotes: 0

TheMadTechnician
TheMadTechnician

Reputation: 36277

Ok, a few things here... You really seem to like the Split() method. You may want to look into some alternatives, like this:

$ActiveBatchVar = @(@("1000","1005"),@("1306","1345"),@("2300","2305"))

See what we did there? It's an array of arrays. @() is the array notation. So I have an array, with 3 arrays in it.

I'm not real familliar with structs, but I am familliar with custom objects, so I would use that if it were me. Then you could do something like:

$SWArray = @() #That's an empty array, we'll add things to it now that it exists
ForEach ($Batch in $ActiveBatchVar){
    $SWArray += New-Object PSObject -Property @{
        SWStart = $Batch[0]
        SWEnd = $Batch[1]
    }
}

So then we change the last bit so that you are assigning $time just before your next loop to keep it as accurate as possible, and correct the ForEach just a little and the whole thing would look like this:

$ActiveBatchVar = @(@("1000","1005"),@("1306","1345"),@("2300","2305"))

$SWArray = @()
ForEach ($Batch in $ActiveBatchVar){
    $SWArray += New-Object PSObject -Property @{
        SWStart = $Batch[0]
        SWEnd = $Batch[1]
    }
}
Write-Host Complete array...
$SWArray

$time = date -f HHmm
ForEach($SW in $SWArray) {
    If ($time -ge $SW.SWStart -and $time -lt $SW.SWEnd) {
        Write-Host "Wohoo we have hit a service window service window..."
    }
}

Upvotes: 1

Cole9350
Cole9350

Reputation: 5560

ForEach-Object ($SWArray) {}

This is the wrong syntax, you should use the keyword in

Foreach-Object ($array in $SWArray) {}

Upvotes: 0

Raf
Raf

Reputation: 10097

Minimum changes:

ForEach-Object ($SWArray) {

to

$SWArray | % {

Also your last Write-Host should enclose the message in quoes ie

{Write-Host "Wohoo..."}

Upvotes: 0

Related Questions