How to save Powershell output to specific folder on the local machine when running an Invoke command on remote machine

浪尽此生 提交于 2021-02-08 10:06:14

问题


I am using powershell to pull basic computer information from all computers on a LAN. These computers are not, and will never be on, a domain. I have had some success in my test runs getting the output for all of the machines to save into the c:\scripts folder on the host machine. I am, however, having to use the Invoke-command for every cmdlet so that I can put the Output destination outside of the {}.

$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"

I would prefer not to have to do this and it becomes problematic when I have to use If/Else statements, where, because I cannot put the destination outside of braces, I get a file cannot be found error (since it is trying to save on the remote host). I tried using a share instead, in the below but now am getting an access to the file path is denied error.

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"
}

How do I run this one a remote machine using Invoke-Command but save the output to the local c:\scripts folder?


回答1:


If the goal is to give yourself the option to output to multiple files on the calling system, you could use a hash table ($results) inside of your script block to store your results. Then output that table at the end of your script block. Based on those keys/values, you could output to file.

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"
}

If the goal is to simply output all data to one location, you can simply store your Invoke-Command result into a variable. Then write the variable contents to file:

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

If you are looking to capture Write-Host output in a variable, you will need to send the information stream to the success stream ( { script block } 6>&1 }




回答2:


You can redirect the output

$YourScriptBlock = { your script }

$result = Invoke-Command -ScriptBlock $YourScriptBlock 4>&1 -Computer $c -Credential $c

Afterwards the contents are in $result

write-output $result


来源:https://stackoverflow.com/questions/62541558/how-to-save-powershell-output-to-specific-folder-on-the-local-machine-when-runni

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!