如何附加到脚本块作业中的文件?

时间:2014-06-28 12:12:29

标签: powershell

我想要的输出文件有问题。

我收到“空路径”错误,

No se puede enlazar el argumento al parámetro 'Path' porque es nulo.
    + CategoryInfo          : InvalidData: (:) [Add-Content], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.AddContentCommand
    + PSComputerName        : localhost

如果我在脚本块中移动$ outputReport,有时会出现错误,说明其他进程正在使用文件“x”:

El proceso no puede obtener acceso al archivo 'C:\Users\mario\Desktop\Report700.csv' porque está siendo utilizado en otro proceso.
    + CategoryInfo          : WriteError: (C:\Users\mario\Desktop\Report700.csv:String) [Add-Content], IOException
    + FullyQualifiedErrorId : GetContentWriterIOError,Microsoft.PowerShell.Commands.AddContentCommand
    + PSComputerName        : localhost

我的来源是这样的CSV:

pc1,user1
pc2,user2
pc3,user3

CODE:

$csvLocation = '~\desktop\test.csv'
$csv = import-csv $csvLocation -Header PCName, User

#Output File:
$outputReport = "~\Desktop\Report700.csv"

#desktop cuota:
    # info:
    # "209715200" Bytes = 200 MB
    # "1048576"   Bytes = 1   MB

$cuota = "209715200"
$cuotaTranslate = "$($cuota / 1MB) MB"

Write-Host "Cuota is set to $cuotaTranslate"

#ScriptBlock
$sb = {
    Param($computer, $username)

    if (!(Test-Connection -Quiet -count 2 -computer $computer)) { return }

        $w7path = "\\$computer\c$\users\$username\desktop"       
        $desktopSize = (Get-ChildItem -Recurse -force $w7path | Measure-Object -ErrorAction "SilentlyContinue" -property length -sum) 

        if($($desktopSize.sum) -gt $cuota){

            $newline = "{0},{1},{2}" -f $computer,$Username,"$("{0:N0}" -f $($desktopSize.sum / 1MB)) MB"
            $newline | Add-Content $outputReport
        }


}


$csv | % {
  Start-Job -ScriptBlock $sb -ArgumentList $_.PCName, $_.User
}

# wait for completion
do {
  Start-Sleep -Milliseconds 100
} while (Get-Job -State 'Running')

# cleanup
Get-Job | % {
  Receive-Job -Id $_.Id
  Remove-Job -Id $_.Id
}

Write-Host "All done!"

2 个答案:

答案 0 :(得分:1)

我可以指出的几点是

使用绝对路径名而不是相对路径。喜欢

而不是说

$csvLocation = '~\desktop\test.csv'

将其更改为

$csvLocation = 'C:\Users\blah_user\Desktop\test.csv'

以同样方式更改$outputReport

以下命令

$newline = "{0},{1},{2}" -f $computer,$Username,"$("{0:N0}" -f $($desktopSize.sum / 1MB)) MB"
$newline | Add-Content $outputReport

可以简单地说就像

"{0},{1},{2}" -f $computer,$Username,"$("{0:N0}" -f $($desktopSize.sum / 1MB)) MB" | OUT-FILE C:\Users\blah_user\Desktop\Report700.csv

(OR)甚至更好,只需将输出附加到文件

"{0},{1},{2}" -f $computer,$Username,"$("{0:N0}" -f $($desktopSize.sum / 1MB)) MB" >>  C:\Users\blah_user\Desktop\Report700.csv 

答案 1 :(得分:1)

此处有scope个问题。 scriptblock中的变量$outputReport是与脚本范围中的变量$outputReport不同的变量。如果您希望scriptblock中的变量具有与外部变量相同的值,则需要通过-ArgumentList参数将该值传递到scriptblock中:

#ScriptBlock
$sb = {
    Param($computer, $username, $outputReport)
    ...
}

$csv | % {
  Start-Job -ScriptBlock $sb -ArgumentList $_.PCName, $_.User, $outputReport
}

但是,这样做会产生其他问题,例如多个并行作业对输出文件的并发访问。您可以通过从脚本块中删除| Add-Content $outputReport并在从已完成的作业中收集文件时将所有输出写入文件来避免这种情况。

为此,请将其删除:

if($($desktopSize.sum) -gt $cuota){

    $newline = "{0},{1},{2}" -f $computer,$Username,"$("{0:N0}" -f $($desktopSize.sum / 1MB)) MB"
    $newline | Add-Content $outputReport
}

并添加:

Get-Job | % {
  Receive-Job -Id $_.Id
  Remove-Job -Id $_.Id
} | Out-File $outputReport