PowerShell中如何让if判断结果正确写入哈希表
核心问题排查
你的脚本无法正常填充哈希表,是几个明确的代码错误,不存在复杂的嵌套逻辑兼容问题:
- 变量拼写不一致:代码中先后出现
$hastable(拼写漏了字母s)和$hashtable两个完全独立的PowerShell变量。你给拼写正确的$hashtable添加键值对,最后输出的却是拼写错误、始终为空的$hastable,自然拿不到任何结果。 - 哈希表初始化位置错误:将
$哈希表 = @{}写在内层的scope循环中,每遍历一个作用域、一个主机名,就会把之前存储的所有键值对清空重置。哪怕变量拼写完全正确,最终也只会残留最后一次循环的临时数据。正确的初始化位置是所有循环的最外层,整个脚本运行过程中仅创建一次哈希表实例。 - DHCP cmdlet传参逻辑低效且不稳定:直接将scope对象通过管道传给
Get-DhcpServerV4Lease,部分环境下会出现参数绑定失效、返回空结果的问题;且直接调用.Add()方法没有做键值判重,遇到同一个作用域下重复匹配的主机名,会直接抛出“键已存在”的运行中断错误。 - 缺少基础空值判断:如果某个授权DHCP服务器在线但未配置任何IPv4作用域,脚本会直接抛出终止性错误。
修复后的可运行代码
# 所有循环最外层仅初始化一次结果哈希表 $resultHash = @{} # 获取域内所有授权的DHCP服务器 $dhcpServers = Get-DhcpServerInDC # 提前读取目标主机名列表,避免循环内重复读文件 $targetHostnames = Get-Content -Path "C:\script\HostNameList.txt" foreach ($server in $dhcpServers) { $serverFQDN = $server.DnsName # 获取当前服务器下所有IPv4作用域,跳过无作用域的异常服务器 $scopes = Get-DHCPServerv4Scope -ComputerName $serverFQDN -ErrorAction SilentlyContinue if (-not $scopes) { Write-Warning "DHCP服务器 $serverFQDN 无可用IPv4作用域,跳过处理" continue } foreach ($scope in $scopes) { # 直接使用ScopeId参数拉取当前作用域的所有租约,避免管道传参的兼容性问题 $scopeLeases = Get-DhcpServerV4Lease -ComputerName $serverFQDN -ScopeId $scope.ScopeId.IPAddressToString foreach ($targetHost in $targetHostnames) { # 按通配规则匹配主机名 $matchedLease = $scopeLeases | Where-Object HostName -like "$targetHost*" if ($matchedLease) { # 用"服务器\作用域"拼接为哈希表键,避免多服务器下同名校验作用域导致的键重复 $hashKey = "$serverFQDN\$($scope.Name)" # 用索引赋值代替Add方法,重复键自动覆盖,不会触发运行错误 $resultHash[$hashKey] = $matchedLease.HostName } } } } # 输出最终的完整哈希表 $resultHash
优化说明
- 执行效率优化:原代码会对每个作用域、每个主机名单独发起一次DHCP远程查询,大量重复请求会拖慢执行速度。修改后先把单个作用域的所有租约拉取到本地,再做主机名匹配,查询次数大幅减少,执行速度可提升数倍。
- 结果准确性优化:原代码直接用作用域名当哈希表键,遇到多台DHCP服务器上重名的作用域时,会出现值被错误覆盖的问题。修改后拼接服务器名作为键的组成部分,可完整保留租约的定位信息,不会出现串数据的情况。
- 健壮性优化:去掉了会触发运行中断的
.Add()方法,改用哈希表的索引赋值语法,遇到重复匹配的场景不会直接报错中断。
内容的提问来源于stack exchange,提问作者feelsgood
相关产品推荐
相关产品推荐

