Object Powershell-从多个cmdlet导出输出

Object Powershell-从多个cmdlet导出输出,object,powershell,formatting,output,cmdlet,Object,Powershell,Formatting,Output,Cmdlet,我曾多次在导出来自多个cmdlet的数据时遇到问题 例如:我试图使用WMI导出打印机列表和其他相关信息,但提取所有信息需要两个cmdlet: Get-WmiObject -Class Win32_Printer ` -ComputerName $Computer -Credential $cred 而且 Get-WmiObject -Class Win32_PrinterConfiguration ` -ComputerName $Computer -Crede

我曾多次在导出来自多个cmdlet的数据时遇到问题

例如:我试图使用WMI导出打印机列表和其他相关信息,但提取所有信息需要两个cmdlet:

Get-WmiObject -Class Win32_Printer `
        -ComputerName $Computer -Credential $cred
而且

Get-WmiObject -Class Win32_PrinterConfiguration `
        -ComputerName $Computer -Credential $cred
我已经创建了一个对象,将数据导入其中,以便可以将其导出:

$CSVData = New-Object PSObject
$CSVData | Add-Member -MemberType NoteProperty -Name "Name" -Value ""
$CSVData | Add-Member -MemberType NoteProperty -Name "DriverName" -Value ""
$CSVData | Add-Member -MemberType NoteProperty -Name "Location" -Value ""
$CSVData | Add-Member -MemberType NoteProperty -Name "PrintProcessor" -Value ""
$CSVData | Add-Member -MemberType NoteProperty -Name "PortName" -Value ""
$CSVData | Add-Member -MemberType NoteProperty -Name "Duplex" -Value ""
$CSVData | Add-Member -MemberType NoteProperty -Name "Color" -Value ""
$CSVData | Add-Member -MemberType NoteProperty -Name "PrintQuality" -Value ""

$CSVData.Name = @()
$CSVData.DriverName = @()
$CSVData.Location = @()
$CSVData.PrintProcessor = @()
$CSVData.PortName = @()
$CSVData.Duplex = @()
$CSVData.Color = @()
$CSVData.PrintQuality = @()
我试着这样安排:

    $PrinterConfig = Get-WmiObject -Class Win32_PrinterConfiguration `
        -ComputerName $Computer -Credential $cred |
            Select-Object Duplex,
                          Color,
                          PrintQuality

    $CSVData.Duplex += $PrinterConfig.Duplex
    $CSVData.Color += $PrinterConfig.Color
    $CSVData.PrintQuality += $PrinterConfig.PrintQuality
        $PrinterInfo = Get-WmiObject -Class Win32_Printer `
        -ComputerName $Computer -Credential $cred | 
            Select-Object Name,
                          DriverName,
                          Location,
                          PrintProcessor,
                          PortName |
                ForEach-Object {
                    $CSVData.Name += $_.Name
                    $CSVData.DriverName += $_.DriverName
                    $CSVData.Location += $_.Location
                    $CSVData.PrintProcessor += $_.PrintProcessor
                    $CSVData.PortName += $_.PortName
                }
$CSVData | Export-Csv -Path c:\temp\printers.csv $OutDir
ComputerName   : myComputer
Name           : Microsoft XPS Document Writer
DriverName     : Microsoft XPS Document Writer
Location       :
PrintProcessor : winprint
PortName       : XPSPort:
Duplex         : False
Color          : 2
PrintQuality   : 600
像这样:

    $PrinterConfig = Get-WmiObject -Class Win32_PrinterConfiguration `
        -ComputerName $Computer -Credential $cred |
            Select-Object Duplex,
                          Color,
                          PrintQuality

    $CSVData.Duplex += $PrinterConfig.Duplex
    $CSVData.Color += $PrinterConfig.Color
    $CSVData.PrintQuality += $PrinterConfig.PrintQuality
        $PrinterInfo = Get-WmiObject -Class Win32_Printer `
        -ComputerName $Computer -Credential $cred | 
            Select-Object Name,
                          DriverName,
                          Location,
                          PrintProcessor,
                          PortName |
                ForEach-Object {
                    $CSVData.Name += $_.Name
                    $CSVData.DriverName += $_.DriverName
                    $CSVData.Location += $_.Location
                    $CSVData.PrintProcessor += $_.PrintProcessor
                    $CSVData.PortName += $_.PortName
                }
$CSVData | Export-Csv -Path c:\temp\printers.csv $OutDir
ComputerName   : myComputer
Name           : Microsoft XPS Document Writer
DriverName     : Microsoft XPS Document Writer
Location       :
PrintProcessor : winprint
PortName       : XPSPort:
Duplex         : False
Color          : 2
PrintQuality   : 600
然后我像这样导出:

    $PrinterConfig = Get-WmiObject -Class Win32_PrinterConfiguration `
        -ComputerName $Computer -Credential $cred |
            Select-Object Duplex,
                          Color,
                          PrintQuality

    $CSVData.Duplex += $PrinterConfig.Duplex
    $CSVData.Color += $PrinterConfig.Color
    $CSVData.PrintQuality += $PrinterConfig.PrintQuality
        $PrinterInfo = Get-WmiObject -Class Win32_Printer `
        -ComputerName $Computer -Credential $cred | 
            Select-Object Name,
                          DriverName,
                          Location,
                          PrintProcessor,
                          PortName |
                ForEach-Object {
                    $CSVData.Name += $_.Name
                    $CSVData.DriverName += $_.DriverName
                    $CSVData.Location += $_.Location
                    $CSVData.PrintProcessor += $_.PrintProcessor
                    $CSVData.PortName += $_.PortName
                }
$CSVData | Export-Csv -Path c:\temp\printers.csv $OutDir
ComputerName   : myComputer
Name           : Microsoft XPS Document Writer
DriverName     : Microsoft XPS Document Writer
Location       :
PrintProcessor : winprint
PortName       : XPSPort:
Duplex         : False
Color          : 2
PrintQuality   : 600
问题是实际上没有导出任何有用的数据,我不知道如何正确组合这两个cmdlet的输出

很可能有一种更优雅的方式来做到这一点


请帮忙

首先,您可能希望以稍微不同的方式进行查询。这种方式只会返回您真正关心的数据(速度也快了一点):

现在您有了两个数组,您必须找到某种方法来连接来自类的数据(有许多方法,大多数比本例更复杂)。您需要遍历每个打印机对象并找到相关的打印机配置对象。两个数组都具有“Name”属性:

    foreach ( $printer in $printers ) {
        $printerCfg = $printerCfgs | where { $_.Name -eq $printer.Name }
这样,您就可以针对每个打印机和打印机配置对象创建单个对象

        $printerInfo = New-Object PSObject -Property @{
            ComputerName = $ComputerName
            Name = $printer.Name
            DriverName = $printer.DriverName
            Location = $printer.Location
            PrintProcessor = $printer.PrintProcessor
            PortName = $printer.PortName
            Duplex = $printerCfg.Duplex
            Color = $printerCfg.Color
            PrintQuality = $printerCfg.PrintQuality
        }
接下来,您希望以正确的顺序返回数据,以便csv可读(在select关闭上面的foreach循环之后的},您需要;):

最后,您可能需要从多台计算机上获取这些信息,并将其全部保存在一个csv文件中。有几种方法,您可以将上面的代码放入ps1文件中,也可以创建一个函数,将计算机名作为参数和单个cred对象,这样您就不必为每个WMI查询重新验证。我自己更喜欢函数,我把它们放在我的ps配置文件中,或者在其中做点注释(更容易跟踪IMO):

对一台计算机使用此函数的步骤

get-printerinfo myComputer
提示我输入用户/通行证,然后返回如下内容:

    $PrinterConfig = Get-WmiObject -Class Win32_PrinterConfiguration `
        -ComputerName $Computer -Credential $cred |
            Select-Object Duplex,
                          Color,
                          PrintQuality

    $CSVData.Duplex += $PrinterConfig.Duplex
    $CSVData.Color += $PrinterConfig.Color
    $CSVData.PrintQuality += $PrinterConfig.PrintQuality
        $PrinterInfo = Get-WmiObject -Class Win32_Printer `
        -ComputerName $Computer -Credential $cred | 
            Select-Object Name,
                          DriverName,
                          Location,
                          PrintProcessor,
                          PortName |
                ForEach-Object {
                    $CSVData.Name += $_.Name
                    $CSVData.DriverName += $_.DriverName
                    $CSVData.Location += $_.Location
                    $CSVData.PrintProcessor += $_.PrintProcessor
                    $CSVData.PortName += $_.PortName
                }
$CSVData | Export-Csv -Path c:\temp\printers.csv $OutDir
ComputerName   : myComputer
Name           : Microsoft XPS Document Writer
DriverName     : Microsoft XPS Document Writer
Location       :
PrintProcessor : winprint
PortName       : XPSPort:
Duplex         : False
Color          : 2
PrintQuality   : 600
要针对当前工作目录中名为list.txt的文件中的计算机列表使用它,请执行以下操作:

$cred = Get-Credential
cat .\list.txt | %{ get-printerinfo -ComputerName $_ -cred $cred }  
要使用list.txt并将输出置于csv中,请执行以下操作:

$cred = Get-Credential
cat .\list.txt | %{ get-printerinfo -ComputerName $_ -cred $cred } | Export-Csv .\myPrinterData.csv -NoTypeInformation
更新(新脚本):
我要补充的是,“Name”属性可能会返回不准确的结果,如果您有多个同名打印机,那么还有其他方法可以加入这两个类。效果不错!谢谢Brendan我觉得有必要在这方面做更多。。。我想对脚本中的计算机列表运行foreach循环。我已将我提出的脚本附加到我的原始问题中。知道我遗漏了什么吗?你是如何生成你的列表的?我会将[string[]从高级参数中去掉。此外,您可能不想在脚本/函数中写入输出$PrinterInfo或执行$PrinterInfo |格式表(或格式列表、ft、fl等),因为如果您有输出数据,您将无法使用导出csv。