Powerhell, jobs and passsing out from child to parent

Soldato
Joined
8 Mar 2005
Posts
3,676
Location
London, UK
Proper head scratcher here;Below is a child script which is called from a parent which acts simply as a wrapper to execute multiple threads of the child along with a feeder file containing server names. The wrapper works with various child scripts I've created without issue or fault.

The script simply checks whether a service is running, if not it then starts it and send out a mail. What isn't working is my attempt to pass some detail back to the parent as defined in as a PSObject for output;

Code:
Param($computer, servicename) 
$datetime =  get-date
$servicecondition
function FuncCheckService{
   # param($RemoteServer)
    param($RemoteServer,$ServiceName)
    $arrService = Get-Service -Name $ServiceName -computername $RemoteServer
    if ($arrService.Status -ne "Running"){
        
         #Creating Custom PSObject For Output 
            $object = New-Object -TypeName PSObject -Property @{ 
              Computer=$RemoteServer
              Service=$ServiceName 
              Timestamp=$datetime 
              testdata="test"
             
              
              
              } | Select-Object * #Computer, Service, Timestamp, testdata 
               
          #write-output $object
        
        Start-Service $ServiceName -computername $RemoteServer

        (get-service -ComputerName $RemoteServer -Name $ServiceName).Start()
        
     

        FuncMail -To "[email protected]" -From "[email protected]"  -Subject "Servername ($RemoteServer) : ($ServiceName) service started." -Body "$datetime WARNING Service $ServiceName was restarted" -smtpServer "smtpfoo"
    
      
    
    
    }
}
 
 
 
 
function FuncMail {
    #param($strTo, $strFrom, $strSubject, $strBody, $smtpServer)
    param($To, $From, $Subject, $Body, $smtpServer)
    $msg = new-object Net.Mail.MailMessage
    $smtp = new-object Net.Mail.SmtpClient($smtpServer)
    $msg.From = $From
    $msg.To.Add($To)
    $msg.Subject = $Subject
    $msg.IsBodyHtml = 1
    $msg.Body = $Body
    $smtp.Send($msg)
}

FuncCheckService -RemoteServer $computer -ServiceName $servicename


Below is the parent wrapper;
Code:
Param($ScriptFile = $(Read-Host "Enter the script file"), 
    $ComputerList = $(Read-Host "Enter the Location of the serverlist"),
    $MaxThreads = 30,
    $SleepTimer = 100,
    $MaxWaitAtEnd = 600,
    $OutputType = "Gridview")
    
$Computers = Get-Content $ComputerList
 
 
"Killing existing jobs . . ."
Get-Job | Remove-Job -Force
"Done."
 
$i = 0
 
ForEach ($Computer in $Computers){
    While ($(Get-Job -state running).count -ge $MaxThreads){
        Write-Progress  -Activity "Creating Server List" -Status "Waiting for threads to close" -CurrentOperation "$i threads created - $($(Get-Job -state running).count) threads open" -PercentComplete ($i / $Computers.count * 100) Start-Sleep -Milliseconds $SleepTimer
    }
 
"Starting job - $Computer"
    $i++
    Start-Job -FilePath $ScriptFile -ArgumentList $Computer -Name $Computer | Out-Null
    Write-Progress  -Activity "Creating Server List" -Status "Starting Threads" -CurrentOperation "$i threads created - $($(Get-Job -state running).count) threads open" -PercentComplete ($i / $Computers.count * 100)
    
}
 
$Complete = Get-date
 
While ($(Get-Job -State Running).count -gt 0){
    $ComputersStillRunning = ""
    ForEach ($System  in $(Get-Job -state running)){$ComputersStillRunning += ", $($System.name)"}
    $ComputersStillRunning = $ComputersStillRunning.Substring(2)
    Write-Progress  -Activity "Creating Server List" -Status "$($(Get-Job -State Running).count) threads remaining" -CurrentOperation "$ComputersStillRunning" -PercentComplete ($(Get-Job -State Completed).count / $(Get-Job).count * 100)
    If ($(New-TimeSpan $Complete $(Get-Date)).totalseconds -ge $MaxWaitAtEnd){"Killing all jobs still running . . .";Get-Job -State Running | Remove-Job -Force}
    Start-Sleep -Milliseconds $SleepTimer
}
 
"Reading all jobs"
 
If ($OutputType -eq "Text"){
    ForEach($Job in Get-Job){
        "$($Job.Name)"
        "****************************************"
        Receive-Job $Job | Select-Object * -ExcludeProperty RunspaceId | Export-CSV 'Output.csv'  -NoTypeInformation
        " "
    }
}
ElseIf($OutputType -eq "Gridview"){

    Get-Job | Receive-Job | Select-Object * | ConvertTo-Csv -NoTypeInformation | % {$_.Replace('"','')} | Out-File 'Output.csv' 
}

Bemused! Any pointers, much appreciated.

Cheers Paul.
 
Soldato
Joined
25 Mar 2004
Posts
15,902
Location
Fareham
Before anything else just how many servers is this checking against?

Reason I ask is because I would be sorely tempted to use WMI to query the service status across all servers (assuming the list is not too large), then simply filter that list for a global "it's not running on these servers" list, that way you only call the Start-Service on a specified list, and you only get one email.
 
Soldato
OP
Joined
8 Mar 2005
Posts
3,676
Location
London, UK
100s

I'm definitely missing something with the child script, as running it outside of the parent confirms it's not outputting anything.

Code:
#Creating Custom PSObject For Output          "Creating Output"
            $AdapterProp = @{ 
              Computer=$RemoteServer
              Service=$ServiceName 
              Timestamp=$datetime 
              testdata="test"
        
              }
              
              New-Object -TypeName PSObject -Property $AdapterProp | Select-Object Computer, Service, Timestamp, testdata

So altered the section slightly and it now does generate the required output, however it isn't passing it to the wrapper. Hmm

The mail notification function I'll move to the wrapper, so it will only produce s single email with the conslidated output from the childs.
 
Last edited:
Back
Top Bottom