You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 00:25:26