【问题标题】:Why is my foreach variable not going to my output in PowerShell after each iteration?为什么每次迭代后我的 foreach 变量都不会在 PowerShell 中输出?
【发布时间】:2021-04-07 14:44:11
【问题描述】:

我有 DHCP 脚本,可以在 DHCP 服务器上的所有范围内查找匹配的主机名

  • 我首先获取所有 DHCP 服务器并导入主机名 .txt
$list = Get-Content C:\script\HostNameList.txt #Defines content it pulls as list 
$DHServers = Get-DhcpServerInDC #gives variable name for loop

 # Gets all DHCP servers ands scopes 
    foreach ($Server in $DHServers){
        $scopes = Get-DHCPServerv4Scope -ComputerName $Server.dnsname #get all scopes
    }
  • 我遍历主机名和范围列表以寻找匹配项。这里的某个地方是我的问题
$Output = foreach ($hostname in $list) { #Calls each item in list a hostname and sends to output
    if (test-connection -count 1 -computername $hostname -quiet) #With 1 ping, check if hostname is online
    {   
        foreach ($scope in $scopes){ 
            if($scope | Get-DhcpServerV4Lease -ComputerName $server.dnsname | Where-Object HostName -like "$hostName*" ) #compares the hostname to lease to find which scope it is in
            { $scope.name } #return scope it found hostname in
        }
        [PSCustomObject]@{ #Rename varibles in data pull for output file
        Asset = $hostname
        Location = $scope.name #only want the name of the scope
        Status = "Online"
        }
    }   

    else #statement if hostname is not online
    { 
        Write-host "$hostname Is offline, only Last Location is known. $hostname was added to the output file." -BackgroundColor DarkRed
        [PSCustomObject]@{
        Asset = $hostname
        Location = $scope.name #only want the name of the scope, since the name = Location
        Status = "Offline"
        }
    }
}
$Output #show output in powershell
$Output | Export-Csv -Path C:\script\Asset_Result.csv -NoTypeInformation #outputs .csv
  • 这就是它正在做的事情,输出重复 DHCP 作用域列表中的最后一项。
Asset    Location         Status
-----     --------         ------
A847    Public Internet      Online
A261    Public Internet      Offline
A201    Public Internet      Online
  • 这是应该做的
Asset    Location         Status
-----     --------         ------
A847        FLoor 1         Online
A261      West 1st FL       Offline
A201        Floor 3         Online

我怎样才能在我的 if($scope | ... 语句在每次迭代后转到我的 PSCustomObject?

【问题讨论】:

  • 您是否必须将其放入您找到的匹配项中?含义:if($scope | Get-DhcpServerV4Lease -ComputerName $server.dnsname | Where-Object HostName -like "$hostName*" ) { $scope.name; [PSCustomObject]@{...

标签: powershell foreach scope iteration dhcp


【解决方案1】:

这个:

foreach ($Server in $DHServers){
  $scopes = Get-DHCPServerv4Scope -ComputerName $Server.dnsname #get all scopes
}

是 - 在净效应 - 相当于:

$scopes = Get-DHCPServerv4Scope -ComputerName $DHServers[-1].dnsname #get all scopes

也就是说,你不断地重新分配给循环体中的同一个变量 ($scopes),替换之前的值,这样你最终只能得到 last 的结果循环迭代,对于存储在$DHServers中的最后一个服务器,即$DHServers[-1]


最好的解决方案是依靠 PowerShell 使用诸如 foreach 之类的语句的能力作为表达式,其输出 - 甚至是循环的迭代输出 - 都会自动收集在 [object[]] 数组中(具有两个或更多输出)由 PowerShell:

# Collect the output from *all* Get-DHCPServerv4Scope calls.
[array] $scopes = foreach ($Server in $DHServers) {
  Get-DHCPServerv4Scope -ComputerName $Server.dnsname #get all scopes
}

注意:[array] 类型约束(与 [object[]] 相同)仅在可能只有 一个 输出对象并且您希望确保收集的输出总是是一个数组。

【讨论】:

  • 这也是我的猜测!认为这是他的实际意图一次做一个,但这是有道理的。
  • @AbrahamZinala,是的,考虑到预期的结果,我认为我们可以推断出在数组中收集是有意的(这也可以与 $scopes += ... 在循环中使用,并在之前的 $scopes = @() 初始化,但是这种类型的迭代“附加”到数组效率低下,因此不明智)。
  • @Bryce,如果我理解正确,您必须明确访问 $DHServers 数组元素,如下所示:$i = 0; foreach ($scope in $scopes) { if($scope | Get-DhcpServerV4Lease -ComputerName $DHServers[$i++] ...
  • $DHServers[$i++] 从数组 $DHServers 返回第 i 个元素 - 这假定 $DHServersforeach ($scope in $scopes) 运行时仍在范围内。
  • @BryceHoward,我假设 $scopes$DHServersparallel 数组 - 但情况可能并非如此。老实说,我还没有深入研究您的代码试图做什么。如果您的问题还没有解决,我是否可以建议您创建一个 问题,以重点关注您的后续问题,最好使用MCVE (Minimal, Complete, and Verifiable Example)?完成后,请随时在此处通知我,我很乐意查看。
猜你喜欢
  • 2021-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-18
  • 2014-01-28
  • 1970-01-01
  • 2016-08-19
相关资源
最近更新 更多