【问题标题】:How to save Powershell output to specific folder on the local machine when running an Invoke command on remote machine在远程计算机上运行 Invoke 命令时如何将 Powershell 输出保存到本地计算机上的特定文件夹
【发布时间】:2020-06-24 04:56:35
【问题描述】:

我正在使用 powershell 从 LAN 上的所有计算机中提取基本计算机信息。这些计算机不是,也永远不会在域中。我在测试运行中取得了一些成功,将所有机器的输出保存到主机上的 c:\scripts 文件夹中。但是,我必须对每个 cmdlet 使用 Invoke-command,以便可以将输出目标放在 {} 之外。

$computers = Get-Content -Path 'c:\scripts\livePCs.txt'

foreach ($computer in $computers) {
$username = '$computer\Administrator'
$password = Get-Content 'C:\scripts\encrypted_password.txt' | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PSCredential($username, $password)

# Local Mounted Shares Enumeration
Invoke-Command -Computername $computer -Credential $credential {Get-SmbMapping | Format-Table -AutoSize} | Out-File "c:\scripts\ComputerInformation\$computer.mountedshares.ps.txt"

# Local Shares Enumeration
Invoke-Command -Computername $computer -Credential $credential {Get-SmbShare | Format-Table -AutoSize} | Out-File "c:\scripts\ComputerInformation\$computer.localshares.ps.txt"

我宁愿不必这样做,当我必须使用 If/Else 语句时它会出现问题,因为我不能将目标放在大括号之外,所以我得到一个文件找不到错误(因为它是试图保存在远程主机上)。我尝试在下面使用共享,但现在访问文件路径被拒绝错误。

Invoke-Command -Computername $computer -Credential $credential {
$computername = hostname.exe
If ($PSVersionTable.PSVersion -ge '4.0') {
    If (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
        Get-WindowsOptionalFeature -Online -FeatureName *Hyper-V* | Format-Table -AutoSize | Out-File -Width 1024 "\\$env:computername\scripts\ComputerInformation\$computername.hyperv.admin.ps.txt"
        if (Get-Command Get-VM -ErrorAction SilentlyContinue) {
            Get-VM | Format-Table -AutoSize | Out-File -Width 1024 -Append "c:\scripts\ComputerInformation\$computername.hyperv.admin.ps.txt"
            Get-VM | Get-VMNetworkAdapter | Format-Table -AutoSize | Out-File -Width 1024 -Append "c:\scripts\ComputerInformation\$computername.hyperv.admin.ps.txt"
        } else {
            Write-Host -ForegroundColor Yellow "         Hyper-V feature not installed on this host"
        }
    } else {
        Write-Host -ForegroundColor Red "         You do not have required permissions to complete this task ..."
    }
} else {
    Write-Host -ForegroundColor Red "         This commands requires at least PowerShell 4.0 ... manual inspection is required"
}

如何使用 Invoke-Command 在远程机器上运行此命令,但将输出保存到本地 c:\scripts 文件夹?

【问题讨论】:

    标签: powershell invoke-command


    【解决方案1】:

    如果目标是让您自己选择输出到调用系统上的多个文件,您可以在脚本块内使用哈希表 ($results) 来存储结果。然后在脚本块的末尾输出该表。根据这些键/值,您可以输出到文件。

    foreach ($computer in $computers) {
        $Output = Invoke-Command -Computername $computer -Credential $credential {
        $results = @{}
        $computername = hostname.exe
        If ($PSVersionTable.PSVersion -ge '4.0') {
            If (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
                $HyperV = Get-WindowsOptionalFeature -Online -FeatureName *Hyper-V* | Format-Table -AutoSize
                if (Get-Command Get-VM -ErrorAction SilentlyContinue) {
                    $VMInfo = Get-VM | Format-Table -AutoSize 
                    $VMNic = Get-VM | Get-VMNetworkAdapter | Format-Table -AutoSize
                } else {
                    Write-Host -ForegroundColor Yellow "         Hyper-V feature not installed on this host"
                }
            } else {
                Write-Host -ForegroundColor Red "         You do not have required permissions to complete this task ..."
            }
        } else {
            Write-Host -ForegroundColor Red "         This commands requires at least PowerShell 4.0 ... manual inspection is required"
        }
        $results.Add('HyperV',$HyperV)
        $results.Add('VMInfo',$VMInfo)
        $results.Add('VMNic',$VMNic)
        $results
        }
    
        $Output.HyperV | Out-File -Width 1024 "c:\scripts\ComputerInformation\$computer.hyperv.txt"
        $Output.VMInfo | Out-File -Width 1024 "c:\scripts\ComputerInformation\$computer.VMInfo.txt"
        $Output.VMNic | Out-File -Width 1024 "c:\scripts\ComputerInformation\$computer.VMNic.txt"
    }
    

    如果目标只是将所有数据输出到一个位置,您可以简单地将Invoke-Command 结果存储到一个变量中。然后将变量内容写入文件:

    $Output = Invoke-Command -Computername $computer -Scriptblock { # my code runs here }
    $Output | Out-File "C:\Folder\$computer.txt"
    

    如果您希望在变量中捕获Write-Host 输出,则需要将信息流发送到成功流({ script block } 6>&1}

    【讨论】:

    • 这个问题中的两个代码块都在脚本中,我试图将它们连接到一个 Invoke-Command 脚本块中。当我尝试这样做时,脚本失败了。当我仅在 foreach ($computer in $computers) {} 中运行您发布的那部分时,它几乎可以正常工作。文件名不再更改为以从中提取信息的机器的计算机名称开头。我将前缀从 $computername 更改为 $computer ,但它仍然没有正确保存。所有计算机,保存到相同的文件名。
    • 在循环的情况下,您需要在foreach 循环中捕获输出并输出到文件中。 out-file 语句将在循环结束时发生在关闭 } 之前。要考虑的另一件事是每个输出都有一个属性$pscomputername,它代表运行脚本块的计算机。但是,您需要遍历输出以选择它们。
    • 成功了!!!!!!我能够将所有这些组合到该哈希表中。由于某种原因,脚本停止将文件名中的 $computer 视为变量。我不得不删除引用并阅读它们.....谢谢!
    【解决方案2】:

    你可以重定向输出

    $YourScriptBlock = { your script }
    
    $result = Invoke-Command -ScriptBlock $YourScriptBlock 4>&1 -Computer $c -Credential $c
    

    然后内容在$result中

    write-output $result
    

    【讨论】:

    • 我看到了一次对其中一个 cmdlet 的工作方式,但是我如何让每个单独的输出写入不同的 txt 文档。对于此脚本,在 If/else 之前有三个单独的 cmdlet。我正在尝试将所有 cmdlet 合并在一起。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    • 2013-06-13
    • 2014-07-26
    • 2013-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多