【问题标题】:Using powershell object to execute scripts使用 powershell 对象执行脚本
【发布时间】:2013-08-19 05:41:54
【问题描述】:

使用的 Powershell 版本:3.0

大家好,

我正在尝试创建一个新的 Powershell 管道并在其中执行一个脚本,然后将它产生的输出获取到一个输出变量中,但是我无法从对象内部(从执行脚本)。这样做的重点是我不必管理 $Error 对象,我打算将其用于错误检测。下面是一个例子:

$ps = [Powershell]::Create()

$File = ".\Test2.ps1"
$SortedParams = "-Name blah -Key foo"
$RootDirectory = Get-Location
$ExecutionDirectory = "$RootDirectory\Test3"

$ps.AddCommand("Set-Location").AddParameter("Path", "$ExecutionDirectory")
write-host "COMMAND 1: " $ps.Commands.Commands.Item(0).CommandText

$ps.AddScript("$File $SortedParams")
write-host "COMMAND 2: " $ps.Commands.Commands.Item(1).CommandText

$output = $ps.Invoke()

write-host $output

我应该提到我正在尝试使用以下 3 种方法在执行的脚本中产生输出:

  • 写主机
  • 写输出
  • Write-Verbose(使用 $ps.Streams.Verbose 尝试获取输出,但没有)

非常感谢您提供的任何建议或提示!

【问题讨论】:

    标签: powershell powershell-3.0 jobs start-job


    【解决方案1】:

    除非您觉得有特殊需要以您的方式做事,否则您可能想考虑使用 PowerShell 后台作业。

    后台作业允许您在单独的 PowerShell 实例中运行 PowerShell 命令,然后将这些作业的输出收集到一个变量中(如果您想要这样做的话)。

    查看 about_Jobs 帮助主题以获取更多信息。

    这是一个简单的例子:

    $job = Start-Job -ScriptBlock { "Hello World!" }
    $ret = Receive-Job $job -Wait -AutoRemoveJob
    
    # value of $ret will be "Hello World!"
    

    【讨论】:

    • 谢谢米克科尔!我尝试使用这个逻辑,似乎返回的是命令本身,而不是我的脚本产生的输出。
    • 你能发布你的代码吗?这不是我所期望的,所以看到你正在执行的代码会让你更容易理解到底发生了什么。
    • 代码如下:$job = Start-Job -ScriptBlock { ".\Test2.ps1 -Name "blah" -Key "foo"" } $ret = Receive-Job $job -Wait -AutoRemoveJob Write-host "OUTPUT: " $ret由于这里的格式问题,我不得不把双引号附近的两个“勾号”去掉。
    • 好了。您刚刚获取命令的原因是因为它包含在双引号中,使 PowerShell 认为您只是将字符串文字放入管道中。如果您将脚本块更改为 { .\Test2.ps1 -Name "blah" -Key "foo" },这将使您更接近您正在寻找的内容。您可能还需要提供要运行的脚本的完全限定路径,因为该作业可能不在当前 PowerShell 会话所在的同一文件夹中运行。
    • 太好了,谢谢!格式化问题稍微修正了逻辑,但是当我运行它时,它仍然保留在同一目录中:$job = Start-Job -ScriptBlock { Set-Location "$ExecutionDirectory"; Get-Location }
    【解决方案2】:

    您可以使用 Invoke-Expression cmdlet 调用另一个脚本,并使用 -OutVariable 参数捕获其输出。我建议使用 Out-Null 以便数据不会两次填充到控制台,请随时删除该管道命令。这是一个例子:

    Invoke-Expression -Command "c:\EventLog.ps1" -OutVariable $data | Out-Null
    
    Write-Host $data
    

    这是我在上例中使用的示例脚本中的代码:

    Param($ComputerName = ".")
    
    Get-EventLog -ComputerName $ComputerName -Log application -EntryType Error | 
        Group-Object -Property source | 
        Sort-Object -Property Count -Descending | 
        Format-Table Count, Name -AutoSize
    

    【讨论】:

    • 感谢 Colyn1337 的回复!但是,我有意避免从当前的执行管道调用我的脚本,因此如果我选择手动执行此脚本,我就不必清理 $Error 对象。这实际上是我之前使用的类似实现。如果我找不到当前实现的解决方案,我会考虑使用它!
    • 告诉我更多关于你想要完成的事情。我可能可以提供更多帮助:]
    • 基本上,我正在尝试完成 3 件事: - 调用脚本 - 执行命令 - 将命令输出传递回主脚本以进行日志记录 我故意避免将输出直接推送到每个脚本中的日志文件。我正在尝试在单个脚本中收集所有输出,然后 然后 将输出记录到日志文件中。我还应该提到,我不希望它从当前管道执行,所以我不必管理 $Error 变量清理。
    【解决方案3】:

    检查您的错误流是否有错误:

    $ps.Streams.Error
    

    这对我有用:

    $ps = [Powershell]::Create()
    cd 'C:\Users\Andy\Documents'
    $File = ".\Test2.ps1"
    $SortedParams = "-Name blah -Key foo"
    $RootDirectory = Get-Location
    $ExecutionDirectory = "$RootDirectory\Test3"
    $ps.AddCommand("Set-Location").AddParameter("Path", "$ExecutionDirectory") | Out-Null
    $ps.AddScript("$File $SortedParams") | Out-Null
    $output = $ps.Invoke()
    write-host $output
    

    这显示了我的设置:

    显示文件组织:

    Command: 
    
    tree.com /F /A $ExecutionDirectory
    
    Output: 
    
    C:\USERS\ANDY\DOCUMENTS\TEST3
        Test2.ps1
    

    显示脚本内容:

    Command:
    
    cat "$ExecutionDirectory\Test2.ps1"
    
    Output: 
    
    param (
        $Name,
        $Key
    )
    $Name
    $Key
    

    【讨论】:

      【解决方案4】:

      我正在使用 Invoke-Expression,这是唯一适合我的解决方案:

      test2.ps

      Invoke-Expression .\test1.ps1 | Tee-Object -Variable msg | Out-Null
      write-host "Return: $msg"</code>
      

      还有test1.ps:

      $hola="Testing"
      $hola
      

      呼叫:

      C:\Test>powershell -ExecutionPolicy unrestricted -file test2.ps1
      Return: Testing
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-05-31
        • 1970-01-01
        • 1970-01-01
        • 2020-08-12
        • 2011-06-06
        • 2018-08-14
        • 1970-01-01
        相关资源
        最近更新 更多