PowerShell实现家庭网络主机信息采集与配置脚本构建求助
解决Windows Sandbox网络主机发现、Hosts自动填充及共享映射脚本生成问题
1. 自动识别本地子网(替代硬编码192.168.0/1.x)
不用硬猜子网,直接通过PowerShell获取当前联网网卡的实际子网:
# 获取当前活跃IPv4网卡的子网前缀(排除回环地址) $localSubnet = Get-NetIPAddress -AddressFamily IPv4 -PrefixOrigin Dhcp | Where-Object { $_.InterfaceAlias -notlike "*Loopback*" } | Select-Object -ExpandProperty Prefix # 提取子网段(比如把192.168.1.0/24转换成192.168.1.) $subnetBase = $localSubnet.Split('/')[0].Substring(0, $localSubnet.LastIndexOf('.') + 1)
2. 修复Ping-Subnet的对象处理问题
你执行Ping-Subnet 192.168.1.1 | select Computername无结果,是因为该脚本返回的对象属性不是Computername,而是IPV4Address。先运行命令查看返回属性:
Ping-Subnet 192.168.1.1 | Get-Member
正确提取存活主机IP的方式:
# 扫描整个子网的存活主机 $liveHosts = Ping-Subnet "$subnetBase`1-$($subnetBase)254" | Where-Object { $_.Status -eq "Success" } | Select-Object -ExpandProperty IPV4Address
3. 用PowerShell解析IP对应的主机名(替代nslookup)
别用nslookup的文本输出,直接用.NET类解析,返回结构化对象更易处理:
$hostsList = @() foreach ($ip in $liveHosts) { try { # 解析IP对应的主机名,只取前缀(去掉域名后缀) $hostEntry = [System.Net.Dns]::GetHostEntry($ip) $hostName = $hostEntry.HostName.Split('.')[0] $hostsList += [PSCustomObject]@{ IPAddress = $ip HostName = $hostName } } catch { # 解析失败时,主机名用IP代替 $hostsList += [PSCustomObject]@{ IPAddress = $ip HostName = $ip } } }
4. 自动填充Hosts文件
修改系统Hosts需要管理员权限,先备份再更新:
# 备份原Hosts文件 Copy-Item -Path "C:\Windows\System32\drivers\etc\hosts" -Destination "C:\Windows\System32\drivers\etc\hosts.bak" -Force # 保留原文件注释和已有条目,追加新发现的主机 $existingHosts = Get-Content -Path "C:\Windows\System32\drivers\etc\hosts" $newHostsEntries = $hostsList | ForEach-Object { "$($_.IPAddress) $($_.HostName)" } $finalHosts = $existingHosts + "" + $newHostsEntries # 写入Hosts文件 $finalHosts | Set-Content -Path "C:\Windows\System32\drivers\etc\hosts" -Force -Encoding ASCII
5. 生成共享目录连接脚本
自动分配盘符(从M开始依次往后),生成可直接运行的PowerShell脚本:
$scriptContent = @" `$cred = Get-Credential # Create the drive mapping with the input credentials "@ # 生成M到Z的盘符列表 $driveLetters = 77..90 | ForEach-Object { [char]$_ } $driveIndex = 0 foreach ($hostEntry in $hostsList) { if ($driveIndex -ge $driveLetters.Count) { break } # 避免盘符耗尽 $letter = $driveLetters[$driveIndex] $scriptContent += "`nNew-PSDrive -Name $letter -PSProvider FileSystem -Root \\$($hostEntry.HostName)\Drives -Persist -Credential `$cred" $driveIndex++ } # 保存脚本到桌面 $scriptContent | Set-Content -Path "$env:USERPROFILE\Desktop\MapNetworkShares.ps1" -Force
完整整合脚本
将所有步骤整合为一个脚本,必须以管理员身份运行:
# 加载Ping-Subnet函数(确保Test-ConnectionAsync.ps1在当前目录) . .\Test-ConnectionAsync.ps1 # 1. 自动识别本地子网 $localSubnet = Get-NetIPAddress -AddressFamily IPv4 -PrefixOrigin Dhcp | Where-Object { $_.InterfaceAlias -notlike "*Loopback*" } | Select-Object -ExpandProperty Prefix $subnetBase = $localSubnet.Split('/')[0].Substring(0, $localSubnet.LastIndexOf('.') + 1) # 2. 扫描存活主机 $liveHosts = Ping-Subnet "$subnetBase`1-$($subnetBase)254" | Where-Object { $_.Status -eq "Success" } | Select-Object -ExpandProperty IPV4Address # 3. 解析主机名 $hostsList = @() foreach ($ip in $liveHosts) { try { $hostEntry = [System.Net.Dns]::GetHostEntry($ip) $hostName = $hostEntry.HostName.Split('.')[0] $hostsList += [PSCustomObject]@{ IPAddress = $ip HostName = $hostName } } catch { $hostsList += [PSCustomObject]@{ IPAddress = $ip HostName = $ip } } } # 4. 更新Hosts文件 Copy-Item -Path "C:\Windows\System32\drivers\etc\hosts" -Destination "C:\Windows\System32\drivers\etc\hosts.bak" -Force $existingHosts = Get-Content -Path "C:\Windows\System32\drivers\etc\hosts" $newHostsEntries = $hostsList | ForEach-Object { "$($_.IPAddress) $($_.HostName)" } $finalHosts = $existingHosts + "" + $newHostsEntries $finalHosts | Set-Content -Path "C:\Windows\System32\drivers\etc\hosts" -Force -Encoding ASCII # 5. 生成共享映射脚本 $scriptContent = @" `$cred = Get-Credential # Create the drive mapping with the input credentials "@ $driveLetters = 77..90 | ForEach-Object { [char]$_ } $driveIndex = 0 foreach ($hostEntry in $hostsList) { if ($driveIndex -ge $driveLetters.Count) { break } $letter = $driveLetters[$driveIndex] $scriptContent += "`nNew-PSDrive -Name $letter -PSProvider FileSystem -Root \\$($hostEntry.HostName)\Drives -Persist -Credential `$cred" $driveIndex++ } $scriptContent | Set-Content -Path "$env:USERPROFILE\Desktop\MapNetworkShares.ps1" -Force Write-Host "操作完成!Hosts已更新,共享映射脚本已保存到桌面。"
内容的提问来源于stack exchange,提问作者YorSubs
相关产品推荐
相关产品推荐

