简体   繁体   English

Powershell CSV Output 发行

[英]Powershell CSV Output Issue

Can anyone assist my with explanation as to why I get System.String[] as my Gateway output in the CSV file but it works fine in the ISE view/window.任何人都可以帮助我解释为什么我在 CSV 文件中将 System.String[] 作为我的网关 output 但它在 ISE 视图/窗口中工作正常。

$testcomputers = Get-Content -Path 'C:\Users2\101.txt'
$exportLocation = 'C:\Users2\PingResults.csv'

# Test connection to each computer before getting the inventory info
foreach ($computer in $testcomputers) {
  if (Test-Connection -ComputerName $computer -Quiet -count 1){
    Add-Content -value $computer -path C:\Users2\OnlineComputers.txt
  }else{
    Add-Content -value $computer -path C:\Users2\OfflineComputers.txt
  }
}

#Specify the list of PC names in the line below
$ArrComputers =  Get-Content -Path 'C:\Users2\OnlineComputers.txt'

Clear-Host
foreach ($Computer in $ArrComputers)
{
    $computerSystem = get-wmiobject Win32_ComputerSystem -Computer $Computer
    $computerBIOS = get-wmiobject Win32_BIOS -Computer $Computer
    $computerOS = get-wmiobject Win32_OperatingSystem -Computer $Computer
    $computerCPU = get-wmiobject Win32_Processor -Computer $Computer
    $computerHDD = Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter drivetype=3
    $computerGateway = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Computer $Computer -Filter “IPEnabled=TRUE”
        write-host "System Information for: " $computerSystem.Name -BackgroundColor DarkCyan
        "-------------------------------------------------------"
        "Manufacturer: " + $computerSystem.Manufacturer
        "Model: " + $computerSystem.Model
        "Serial Number: " + $computerBIOS.SerialNumber
        "CPU: " + $computerCPU.Name
        "HDD Capacity: "  + "{0:N2}" -f ($computerHDD.Size/1GB) + "GB"
        "HDD Space: " + "{0:P2}" -f ($computerHDD.FreeSpace/$computerHDD.Size) + " Free (" + "{0:N2}" -f ($computerHDD.FreeSpace/1GB) + "GB)"
        "RAM: " + "{0:N2}" -f ($computerSystem.TotalPhysicalMemory/1GB) + "GB"
        "Operating System: " + $computerOS.caption + ", Service Pack: " + $computerOS.ServicePackMajorVersion
        "User logged In: " + $computerSystem.UserName
        "Last Reboot: " + $computerOS.ConvertToDateTime($computerOS.LastBootUpTime)
        "Gateway: " + $computerGateway.DefaultIPGateway
        ""
        "-------------------------------------------------------"

#Build the CSV file
$csvObject = New-Object PSObject -property @{
    'PCName' = $computerSystem.Name
    'Manufacturer' = $computerSystem.Manufacturer
    'Model' = $computerSystem.Model
    'Service Tag' = $computerBIOS.SerialNumber
    'RAM' = "{0:N2}" -f ($computerSystem.TotalPhysicalMemory/1GB)
    'HDDSize' = "{0:N2}" -f ($computerHDD.Size/1GB)
    'HDDFree' = "{0:P2}" -f ($computerHDD.FreeSpace/$computerHDD.Size)
    'CPU' = $computerCPU.Name
    'OS' = $computerOS.caption
    'SP' = $computerOS.ServicePackMajorVersion
    'User' = $computerSystem.UserName
    'Last_Reboot' = $computerOS.ConvertToDateTime($computerOS.LastBootUpTime)
    'Gateway' = $computerGateway.DefaultIPGateway
    } 

#Export the fields you want from above in the specified order
$csvObject | Select PCName, Manufacturer, Model, OS, SerialNumber, CPU, Ram, User, Last_Reboot, HDDSize, HDDFree, Gateway | Export-Csv 'C:\Users2\results.csv' -NoTypeInformation -Append
}

Here is the ISE output这是 ISE output

System Information for:  WS101161
-------------------------------------------------------
Manufacturer: Dell Inc.
Model: OptiPlex 5070
Serial Number: 7HF8T13
CPU: Intel(R) Core(TM) i5-9500 CPU @ 3.00GHz
HDD Capacity: 237.96GB
HDD Space: 67.87% Free (161.51GB)
RAM: 15.79GB
Operating System: Microsoft Windows 10 Pro, Service Pack: 0
User logged In: 
Last Reboot: 04/28/2022 17:40:52
Gateway: 10.170.1.250
-------------------------------------------------------

And here is the CSV output (User being empty is okay, nobody is signed into this PC at the moment)这是 CSV output(用户为空没关系,目前没有人登录这台电脑)

"PCName","Manufacturer","Model","OS","SerialNumber","CPU","RAM","User","Last_Reboot","HDDSize","HDDFree","Gateway"
"WS101161","Dell Inc.","OptiPlex 5070","Microsoft Windows 10 Pro",,"Intel(R) Core(TM) i5-9500 CPU @ 3.00GHz","15.79",,"4/28/2022 5:40:52 PM","237.96","67.87%","System.String[]"

Thank you for the assistance!感谢您的帮助!

asdasdasd asdasdasd

The main issue that answers your question, the property DefaultIPGateway of the Win32_NetworkAdapterConfiguration class is of the type string[] :回答您问题的主要问题是Win32_NetworkAdapterConfiguration class的属性DefaultIPGatewaystring[]类型:

DefaultIPGateway默认IP网关
Data type : string array数据类型:字符串数组

You need to convert it to string so that Export-Csv can handle it:您需要将其转换为string ,以便Export-Csv可以处理它:

PS /> @{ Gateway = $computerGateway[0].DefaultIPGateway } | ConvertTo-Csv

"Gateway"
"System.String[]"

PS /> @{ Gateway = [string] $computerGateway[0].DefaultIPGateway } | ConvertTo-Csv

"Gateway"
"192.168.0.1"

It is also worth noting that $computerGateway may return an array of IPs in which case you should join them:还值得注意的是$computerGateway可能会返回一个 IP 数组,在这种情况下你应该加入它们:

$computerGateway.DefaultIPGateway -join ', '

Aside from that, there are other issues with your code, for example all Division operations on $computerHDD :除此之外,您的代码还有其他问题,例如$computerHDD上的所有 Division 操作:

$computerHDD.Size / 1GB

Will throw this exception if the host has more than one Physical Disk:如果主机有多个物理磁盘,将抛出此异常

InvalidOperation: Method invocation failed because [System.Object[]] does not contain a method named 'op_Division'. InvalidOperation:方法调用失败,因为[System.Object[]]不包含名为“op_Division”的方法。

Test-NetConnection is not reliable to tell you if you can or cannot connect to a remote host, there may be a firewall blocking ICMP packets and you may have been able to still connect it since the protocol being used in your code is WinRM ( WinRM HTTP uses port 5985 and WinRM HTTPS uses port 5986 ). Test-NetConnection不能可靠地告诉您是否可以连接到远程主机,可能有防火墙阻止 ICMP 数据包,您可能仍然能够连接它,因为您的代码中使用的协议是 WinRM ( WinRM HTTP 使用端口 5985 和 WinRM HTTPS 使用端口 5986 )。

Your code can also be invoked in parallel instead of going one host at a time, Invoke-Command is the best alternative as Lee_Dailey mentions in his helpful comment.您的代码也可以并行调用,而不是一次调用一台主机,正如Lee_Dailey在他的有用评论中提到的那样, Invoke-Command是最好的选择。

Sending information to the console ( Write-Host ) will only slow your script down, I've removed all instances of console output.将信息发送到控制台 ( Write-Host ) 只会减慢你的脚本,我已经删除了控制台 output 的所有实例。

Appending to a file with Export-Csv -Append on each iteration of your loop will also slow your script down, the more Disk I/O the slower the code will be, it is better to collect all output first in memory and then writing to a file once.在循环的每次迭代中使用Export-Csv -Append附加到文件也会减慢脚本速度,磁盘 I/O 越多,代码越慢,最好先在 memory 中收集所有 output 然后写入一个文件一次。

Lastly, Get-WmiObject should be replaced by Get-CimInstance .最后, Get-WmiObject应替换为Get-CimInstance All the WMI Cmdlets are no longer in circulation in newer versions of PowerShell (PowerShell Core).所有 WMI Cmdlet 不再在 PowerShell (PowerShell Core) 的较新版本中流通。 And the CIM Cmdlets have been available since PowerShell 3. No reason to use WMI over CIM.自 PowerShell 以来,CIM Cmdlet 已可用 3.没有理由在 CIM 上使用 WMI。

With all that being said, this is how I would approach your script:尽管如此,这就是我处理您的脚本的方式:

$unavaibleHosts = [System.Collections.Generic.List[string]]::new()
$session = foreach($computer in Get-Content -Path 'C:\Users2\101.txt') {
    try {
        New-PSSession $computer -ErrorAction Stop
    }
    catch {
        $unavaibleHosts.Add($computer)
    }
}

Invoke-Command -Session $session -HideComputerName -ScriptBlock {
    $computerSystem = Get-CimInstance Win32_ComputerSystem
    $computerBIOS = Get-CimInstance Win32_BIOS
    $computerOS = Get-CimInstance Win32_OperatingSystem
    $computerCPU = Get-CimInstance Win32_Processor
    $computerHDD = Get-CimInstance Win32_LogicalDisk -Filter drivetype=3
    $computerGateway = Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE
    
    $hddSize = $computerHDD.ForEach{ "[{0} {1:N2}]" -f $_.DeviceID, ($_.Size / 1GB) } -join ' | '
    $hddFree = $computerHDD.ForEach{ "[{0} {1:P2}]" -f $_.DeviceID, ($_.FreeSpace / $_.Size) } -join ' | '
    # output from these 2 would look like this:
    # HDDSize      : [C: 236.76] | [D: 931.51]
    # HDDFree      : [C: 73.30%] | [D: 81.43%]
    
    [pscustomobject]@{
        'PCName' = $computerSystem.Name
        'Manufacturer' = $computerSystem.Manufacturer
        'Model' = $computerSystem.Model
        'Service Tag' = $computerBIOS.SerialNumber
        'RAM' = "{0:N2}" -f ($computerSystem.TotalPhysicalMemory / 1GB)
        'HDDSize' = $hddSize
        'HDDFree' = $hddFree
        'CPU' = $computerCPU.Name
        'OS' = $computerOS.caption
        'SP' = $computerOS.ServicePackMajorVersion
        'User' = $computerSystem.UserName
        'Last_Reboot' = $computerOS.LastBootUpTime
        'Gateway' = $computerGateway.DefaultIPGateway -join ','
    }
} | Select-Object * -ExcludeProperty RunspaceId | Export-Csv 'C:\Users2\results.csv' -NoTypeInformation

Remove-PSSession $session
$unavaibleHosts # => Is here for you to troubleshoot the failed connections.
# https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-networkadapterconfiguration
# DefaultIPGateway
# Data type: string array
# Access type: Read-only
# Qualifiers: MappingStrings ("Win32Registry|System\\CurrentControlSet\\Services|Parameters|DefaultGateway")
# Array of IP addresses of default gateways that the computer system uses.
# Example: "192.168.12.1 192.168.46.1"


# Your case
$computerGateway = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Computer "DESKTOP-9EPNRSP" -Filter "IPEnabled=TRUE"
$csvObject = New-Object PSObject -property @{
    'Gateway' = $computerGateway.DefaultIPGateway
} 
$csvObject.Gateway.GetType().FullName

# Convert to String 
$computerGateway = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Computer "DESKTOP-9EPNRSP" -Filter "IPEnabled=TRUE"
$csvObject = New-Object PSObject -property @{
    'Gateway' = "$($computerGateway.DefaultIPGateway)"
} 
$csvObject.Gateway.GetType().FullName

#Take first element
$computerGateway = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Computer "DESKTOP-9EPNRSP" -Filter "IPEnabled=TRUE"
$csvObject = New-Object PSObject -property @{
    'Gateway' = $computerGateway.DefaultIPGateway[0]
} 
$csvObject.Gateway.GetType().FullName

#Generate with comma sepparated - █ Recommended █
$computerGateway = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Computer "DESKTOP-9EPNRSP" -Filter "IPEnabled=TRUE"
$csvObject = New-Object PSObject -property @{
    'Gateway' = [string]::Join(",", $computerGateway.DefaultIPGateway)
} 
$csvObject.Gateway.GetType().FullName

Output Output

System.String[]
System.String
System.String
System.String

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM