我在尝试从模块中捕获并显示Get-NetRoute的结果时遇到了问题:
$option = New-CimSessionOption -Protocol $Protocol
$session = New-CimSession -ComputerName $name -Credential $Credentials -SessionOption $option -ErrorAction $ErrorAct;
$res = Get-NetRoute -CimSession $session
Write-Host $res
我最终得到的是垃圾:
MSFT_NetRoute (InstanceID = "???8???8???8???9??55?55:8:8:8:55;") MSFT_NetRoute (InstanceID = "???8???8???8???9??55;55:8:8:8:55;") MSFT_NetRoute (InstanceID = "???8:8:8:9?55?55:8:8:8:55;") MSFT_NetRoute (InstanceID = "???8:8:8:9?55;55:8:8:8:55;") MSFT_NetRoute (InstanceID = ";C?8;@B8;8???9??55?55:8:8:8:55;") MSFT_NetRoute (InstanceID = ";C?8;@B8;8?:?9??55?55:8:8:8:55;") MSFT_NetRoute (InstanceID = ";C?8;@B8;8:9??55?55:8:8:8:55;") MSFT_NetRoute (InstanceID = ";?A8???8???8???9??55;55:8:8:8:55;") MSFT_NetRoute (InstanceID = ";?A8:8:8;9??55;55:8:8:8:55;") MSFT_NetRoute (InstanceID = ";?A8:8:8:9B55;55:8:8:8:55;") MSFT_NetRoute (InstanceID = ":8:8:8:9:55?55;C?8;@B8;8;55;") MSFT_NetRoute (InstanceID = "pp::DD9B55?55DD55;") MSFT_NetRoute (InstanceID = "pp::DD9B55;55DD55;") MSFT_NetRoute (InstanceID = "poB:DD?B;CD??plD??oBDA@?:9;?B55?55DD55;...) MSFT_NetRoute (InstanceID = "poB:DD9@?55?55DD55;") MSFT_NetRoute (InstanceID = "DD;9;?B55;55DD55;")
当我期望的是一个格式正确的表(或者至少是我可以从中获得有效值的$res对象上的属性)。最后,我希望稍后在脚本中执行一些分析并添加来自其他cmdlet的列,以便为我提供远程计算机上的网络配置的完整报告。当我直接在命令行中执行时,如何正确地捕获结果并使其实际显示数据?这是因为我必须像在Foreach对象中一样遍历$res来访问它的结果集中的每一行吗?
编辑:从错误的板上移出
Edit2:这是我的代码清单
Function Get-RemoteRouteData{
[CmdletBinding()]
[OutputType([System.Management.Automation.PSCustomObject])]
param (
[Parameter(Mandatory = $true)]
[string]$Subnet,
[Parameter(Mandatory = $true)]
[object]$Credentials,
[Parameter(Mandatory = $false)]
[string]$Protocol = 'WSMan',
[Parameter(Mandatory = $false)]
[bool]$TableOnly,
[Parameter(Mandatory = $false)]
[string]$ErrorAct = 'SilentlyContinue'
)
if (!$TableOnly)
{
Write-Host "Scanning $subnet for hosts..."
}
#Use PSSubnetScan module for hosts
$computers = Get-PSSubnetScan -IPList $subnet -RevDNS -ICMPTest
$out = @() # Holds list of output objects
$time = Measure-Command {
foreach ($computer in $computers)
{
$name = $computer.RevDNS.Hostname
$ip = $computer.IPAddress.IPAddressToString
$ping = $computer.ICMP.IsActive
#Check to see if we have a host name or can ping. If neither, skip it.
if ((!$null -eq $name) -and (!$true -eq $ping))
{
Continue
}
if (!$TableOnly)
{
Write-Host "Asking $name - $ip for it's Routing Table"
}
$session = $null
try
{
#Use WMI Class directly
#([WMIClass]"\\$name\ROOT\CImv2:Win32_Process").Create("cmd.exe /c ipconfig /registerdns") | Out-Null
#([WMIClass]"\\192.168.1.205\ROOT\CImv2:Win32_Process").Create("cmd.exe /c winrm quickconfig"
#Use Cim Session
#$option = New-CimSessionOption -Protocol $Protocol
$session = New-CimSession -ComputerName $name -Credential $Credentials #-SessionOption $option -ErrorVariable $err;
$res = Get-NetRoute -CimSession $session
$res | Format-List -Property *
Write-Host "Sanity Check..."
}
catch
{
if (!$TableOnly)
{
Write-Host "$ip - $name - FAILED TO GET ROUTING TABLE" -ForegroundColor Red
}
}
finally
{
Remove-CimSession $session
}
}
}
if (!$TableOnly)
{
"`nCompleted in [{0}] milliseconds" -f $time.TotalMilliseconds
}
Write-Host "`n"
}
Get-RemoteRouteData -Subnet 192.168.1.205 -Credentials (Get-Credential)
我添加了最后一行,以便使用已知的IP地址(我的域控制器)运行函数。结果是这样的:
❯ import-module .\RoutingInfo.psm1 -force
PowerShell credential request
Enter your credentials.
User: scott.reeves@bluejacketsoftware.com
Password for user scott.reeves@bluejacketsoftware.com: ************
Scanning 192.168.1.205 for hosts...
Asking bjsdc01.bluejacketsoftware.com - 192.168.1.205 for it's Routing Table
Sanity Check...
scott.reeves@DELL17 C:\dev\WPA\PowerShell\RoutingInfo master ≣ +0 ~1 -1 ! [21:52]
❯
发布于 2021-01-23 20:36:12
已解决:
问题是因为$res变量嵌套在几层括号中,其中最重要的一层是for-eachobject。因为处理还没有完成对整个列表的迭代,所以for-eachobject函数不能返回合理的值,而是内部表示。将$res对象添加到$out集合,最后在函数末尾打印$out集合将返回可用的结果。作为参考,以下是工作代码:
Function Get-RemoteRouteData{
[CmdletBinding()]
[OutputType([System.Management.Automation.PSCustomObject])]
param (
[Parameter(Mandatory = $true)]
[string]$Subnet,
[Parameter(Mandatory = $true)]
[object]$Credentials,
[Parameter(Mandatory = $false)]
[string]$Protocol = 'WSMan',
[Parameter(Mandatory = $false)]
[bool]$TableOnly,
[Parameter(Mandatory = $false)]
[string]$ErrorAct = 'SilentlyContinue'
)
if (!$TableOnly)
{
Write-Host "Scanning $subnet for hosts..."
}
#Use PSSubnetScan module for hosts
$computers = Get-PSSubnetScan -IPList $subnet -RevDNS -ICMPTest
$out = @() # Holds list of output objects
$time = Measure-Command {
foreach ($computer in $computers)
{
$name = $computer.RevDNS.Hostname
$ip = $computer.IPAddress.IPAddressToString
$ping = $computer.ICMP.IsActive
#Check to see if we have a host name or can ping. If neither, skip it.
if ((!$null -eq $name) -and (!$true -eq $ping))
{
Continue
}
if (!$TableOnly)
{
Write-Host "Asking $name - $ip for it's Routing Table"
}
$session = $null
try
{
#Use WMI Class directly
#([WMIClass]"\\$name\ROOT\CImv2:Win32_Process").Create("cmd.exe /c ipconfig /registerdns") | Out-Null
#([WMIClass]"\\192.168.1.205\ROOT\CImv2:Win32_Process").Create("cmd.exe /c winrm quickconfig"
#Use Cim Session
$option = New-CimSessionOption -Protocol $Protocol
$session = New-CimSession -ComputerName $name -Credential $Credentials -SessionOption $option -ErrorVariable $err;
$res = Get-NetRoute -CimSession $session
$out += $res
}
catch
{
if (!$TableOnly)
{
Write-Host "$ip - $name - FAILED TO GET ROUTING TABLE" -ForegroundColor Red
}
}
finally
{
if(!$null -eq $session){
Remove-CimSession $session
}
}
}
}
if (!$TableOnly)
{
"`nCompleted in [{0}] milliseconds" -f $time.TotalMilliseconds
}
Write-Host "`n"
$out
}
Get-RemoteRouteData -Subnet 192.168.1.0/24 -Credentials (Get-Credential)
发布于 2021-01-18 04:39:48
正如@AdminOfThings在评论中所说,只需删除Write-Host
即可。当通过Write-Host
运行时,输出将与
$res -as [string]
或
[string]$res
它已经是一个你可以获得属性的对象,正如你所说的你想要的那样。
您可以使用以下命令查看对象的所有属性
$res | Get-Member
您可以使用以下命令查看所有属性和值
$res | Format-List -Property *
https://stackoverflow.com/questions/65753017
复制相似问题