Reputation: 2195
I have the following code which is parsing an XML file in PowerShell, and then iterating through the entries in the config file (which are backup jobs) and performing backups (by calling functions).
if ($xmlfile.configuration.DBAndFilesBackup.item("MSSQL").haschildnodes) {
$xmlfile.configuration.DBAndFilesBackup.MSSQL.backup |
Start-RSJob -Name {$_.Name} -Throttle 2 -ScriptBlock {
# Begin the Backup
BeginBackup $_.Name $log
# Backup the mssql database
MSSQLBackup $_.Name $_.DBPath $Using:backupdir $Using:backuptempdir
# Backup the files
FilesBackup $_.Name $_.FolderName $_.FilesPath $Using:backupdir $Using:backuptempdir
# End the Backup
EndBackup $_.FolderName $_.Name $log $Using:emailTo $Using:backupdir $Using:backuptempdir
} -FunctionsToLoad BeginBackup,MSSQLBackup,FilesBackup,EndBackup,Mailer,PrintHeader |
Wait-RSJob |
Receive-RSJob |
Out-file "$ScriptDir\logs\corebackup\$ScriptName $($xmlfile.configuration.DBAndFilesBackup.MSSQL.backup.Name) $DateStamp.log"
}
Start-RSJob
is a custom PowerShell module similar to the Start-Job
cmdlet that handles kicking off parallel jobs.
Both RSJob and the native PowerShell Start-Job
cmdlet don't seem to handle PowerShell transcription (logging). Thus I'm utilizing Write-Output
, in addition to Out-File
to capture the output of the jobs.
The problem I've run into is that in the Write-Output
portion of the script I want to include the name of the backup in the log file name. In other words I end up with a file named "corebackup 2015-08-24.log" instead of "corebackup backupname 2015-08-24.log".
The issue is how do I pass $_.Name
to Out-File
. Right now a log is written, but without the job name.
Upvotes: 1
Views: 763
Reputation: 2195
I wasn't able to get any of the above working with throttling. In other words I could get output but then throttling broke, or i could make throttling work but not get output.
The solution I ended up using was to add a bunch of "Write-Output | Out-file $log -Append" to my script every time I want to output something.
Kinda ugly hack - but by using that inside of the scriptblock I can capture the output.
Thanks to everyone for their help and advise.
Upvotes: 0
Reputation: 6920
Then wrap it in the other For-EachObject
block and assign $_.Name
to a variable accessible outside the pipeline. I've looked at the Start-RsJob docs and it should work:
if ($xmlfile.Configuration.DBAndFilesBackup.Item('MSSQL').HasChildNodes) {
$xmlfile.Configuration.DBAndFilesBackup.MSSQL.Backup | ForEach-Object {
$BackupName = $_.Name
$_ | Start-RSJob -Name $BackupName -Throttle 2 -ScriptBlock {
# Begin the Backup
BeginBackup $_.Name $log
# Backup the mssql database
MSSQLBackup $_.Name $_.DBPath $Using:backupdir $Using:backuptempdir
# Backup the files
FilesBackup $_.Name $_.FolderName $_.FilesPath $Using:backupdir $Using:backuptempdir
# End the Backup
EndBackup $_.FolderName $_.Name $log $Using:emailTo $Using:backupdir $Using:backuptempdir
} -FunctionsToLoad BeginBackup,MSSQLBackup,FilesBackup,EndBackup,Mailer,PrintHeader |
Wait-RSJob |
Receive-RSJob |
Out-File "$ScriptDir\logs\corebackup\$ScriptName $BackupName $DateStamp.log"
}
}
P.S. I'm using this module for logging, it captures any output from PS console: Enhanced Script Logging module:
Automatically copy PowerShell console output to a log file (from Output, Error, Warning, Verbose and Debug streams), while still displaying the output at the console. Log file output is prepended with date/time and an indicator of which stream originated the line.
Upvotes: 2
Reputation: 2147
Try this:
Start-RSJob -ArgumentList @($Name) -Throttle 2 -ScriptBlock {
$Name = $args[0]
...
}
Upvotes: 2