脚本块中的引用变量

Referencing variable in scriptblock

我有以下代码,它在 PowerShell 中解析 XML 文件,然后遍历配置文件中的条目(它们是备份作业)并执行备份(通过调用函数)。

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 是一个自定义 PowerShell 模块,类似于处理启动并行作业的 Start-Job cmdlet。

RSJob 和本机 PowerShell Start-Job cmdlet 似乎都不处理 PowerShell 转录(日志记录)。因此,除了 Out-File 之外,我还利用 Write-Output 来捕获作业的输出。

我 运行 遇到的问题是,在脚本的 Write-Output 部分,我想在日志文件名中包含备份名称。换句话说,我最终得到一个名为 "corebackup 2015-08-24.log" 而不是 "corebackup backupname 2015-08-24.log".

的文件

问题是如何将 $_.Name 传递给 Out-File。现在写入日志,但没有作业名称。

然后将其包装在另一个 For-EachObject 块中,并将 $_.Name 分配给管道外可访问的变量。我查看了 Start-RsJob 文档,它应该可以工作:

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。我正在使用这个模块进行日志记录,它捕获来自 PS 控制台的任何输出: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.

试试这个:

Start-RSJob -ArgumentList @($Name) -Throttle 2 -ScriptBlock {
    $Name = $args[0]
    ...
}

我无法使上述任何一项与节流一起使用。换句话说,我可以获得输出但随后节流中断,或者我可以进行节流但无法获得输出。

我最终使用的解决方案是每次我想输出一些东西时在我的脚本中添加一堆"Write-Output | Out-file $log -Append"。

有点难看 - 但通过在脚本块内部使用它,我可以捕获输出。

感谢大家的帮助和建议。