powershell可通过winrm协议批量获取局域网在线windows设备真实主机名:先启用目标机winrm服务并配置可信主机,再基于arp缓存生成ip列表,最后用cim session、invoke-command或dns反向解析三种方式获取主机名。

在 Windows 11 环境中,需快速掌握局域网内所有正在运行的 Windows 设备真实主机名(而非仅 IP),避免因防火墙屏蔽 ICMP 导致 ping 失败而漏判、或因 DNS 解析失败返回空值——PowerShell 可直接调用 WinRM 协议远程获取目标主机名,前提是目标机已启用远程管理且网络可达。
确认并启用目标电脑的 WinRM 服务
WinRM 是 PowerShell 远程执行的底层通道,未启用则无法获取主机名。此步骤必须在每台待扫描的目标电脑上执行(或通过组策略批量部署):
以管理员身份运行 PowerShell,输入:
Enable-PSRemoting -Force
该命令会自动启动 WinRM 服务、配置监听、开放防火墙端口(默认 TCP 5985)、设置服务为自动启动。若目标机处于工作组环境,还需额外运行:
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*" -Force
【注意:生产环境严禁设为 *,应替换为采集机 IP,如 "192.168.1.10"】
生成在线主机 IP 列表(基于 ARP 缓存静默探测)
先不依赖 ping,用系统底层 ARP 行为快速筛出真实在线设备:
在采集机(Windows 11)上以管理员身份打开 PowerShell,执行以下命令(请将 192.168.1 替换为你实际的子网段):
$ipRange = 1..254 | ForEach-Object { "192.168.1.$_" }
$ipRange | ForEach-Object { $null = Test-Connection $_ -Count 1 -Quiet -ErrorAction SilentlyContinue; Start-Sleep -Milliseconds 10 } | Out-Null
Get-NetNeighbor | Where-Object { $_.State -eq 'Reachable' -or $_.State -eq 'Stale' } | Select-Object -ExpandProperty IPAddress | Sort-Object -Unique > "$env:TEMP\live_ips.txt"
这一步输出的是纯 IP 文本列表,保存在临时目录,后续直接读取。它比单纯 ping 更可靠——因为即使 ICMP 被禁,只要设备近期与本机通信过,ARP 表里就有记录。
批量获取主机名(三种方法任选其一)
方法一:使用 CIM Session(推荐,无需凭据交互,适合域环境)
若所有目标机属于同一 Active Directory 域,且当前登录账号有域管理员权限,执行:
$ips = Get-Content "$env:TEMP\live_ips.txt"
$results = foreach ($ip in $ips) { try { $name = (Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName $ip -ErrorAction Stop).Name; [PSCustomObject]@{IP = $ip; Hostname = $name} } catch { [PSCustomObject]@{IP = $ip; Hostname = "访问拒绝或离线"} } }
$results | Export-Csv -Path "$env:USERPROFILE\Desktop\Hostnames_Report.csv" -Encoding UTF8 -NoTypeInformation
方法二:使用 Invoke-Command(支持工作组,但需提前配置凭据)
适用于工作组环境,需手动提供管理员账号密码(明文仅内存驻留):
$cred = Get-Credential
$ips = Get-Content "$env:TEMP\live_ips.txt"
Invoke-Command -ComputerName $ips -Credential $cred -ScriptBlock { $env:COMPUTERNAME } -ErrorAction SilentlyContinue | Select-Object PSComputerName, Value | Export-Csv "$env:USERPROFILE\Desktop\Hostnames_Workgroup.csv" -Encoding UTF8 -NoTypeInformation
方法三:轻量级 DNS 反向解析(最快但不可靠)
仅当本地 DNS 服务器已正确配置 PTR 记录时可用,否则大量返回“Unknown”:
Get-Content "$env:TEMP\live_ips.txt" | ForEach-Object { try { $hostName = [System.Net.Dns]::GetHostByAddress($_).HostName; "$_,$hostName" } catch { "$_,Unknown" } } | Out-File "$env:USERPROFILE\Desktop\Dns_Hostnames.txt"











