Skip to content

Windows 怎么查 IP 归属地?PowerShell 一条命令加一个函数(服务器、日志排查都能用)

在 Windows 服务器上干活的人大概都遇到过这种事:打开安全日志,几百条登录失败记录,来源 IP 一个都不认识;或者防火墙规则里躺着一串要封的地址,你根本不知道它们是哪来的。挨个复制到网页工具里查?几十个 IP 能查到手软。Linux 上一条 curl 就能解决的事,Windows 上很多教程还停留在 2016 年——接口早停服了。这篇用 PowerShell 写一个查归属地的函数,单条查询一条命令,批量查日志自动跑,2026 年还能用,不注册不要 key。

一、什么时候用得上

  • RDP 爆破排查:Windows Server 默认开远程桌面,安全日志里全是暴力破解尝试。把失败登录的来源 IP 筛出来查一遍归属地,海外机房地址直接批量加进防火墙黑名单,比一条条看效率高一个数量级。
  • 外连地址溯源:服务器莫名其妙往外发包,netstat 看到一堆陌生连接,查一下对方 IP 在哪个国家哪个机房,判断是不是中了马在回连。
  • 出口 IP 验证:公司网络走了代理或者换了线路,想知道当前出口 IP 落在哪个地区,一条命令的事,不用开浏览器。

这些场景的共同点:地址数量不小、只想知道「哪个地区哪个运营商」、不想开网页一个个粘。正是脚本该干的活。

二、用哪个接口

IP9 的免费接口:GET https://ip9.com.cn/get 不传参数,直接返回当前请求方的出口 IP 和归属地;GET https://ip9.com.cn/get?ip=<IP> 查指定 IP,IPv4 和 IPv6 都支持。返回 JSON 里有 countryprov(省份)、cityisp(运营商)、lng/lat(城市中心经纬度)等字段,国内 IP 省市齐全,海外 IP 一般只有国家。免费版 60 次/分钟/IP,非法 IP 返回 ret=400

请求时显式带一个浏览器样式的 User-Agent,这类免费接口会对默认特征请求做风控,带 UA 最稳。下面函数里已经处理好了。

三、PowerShell 实现

先说一个 PowerShell 新手必踩的坑:在 PowerShell 里 curl 不是 curl,它是 Invoke-WebRequest 的别名,参数语法完全不一样。查接口用 Invoke-RestMethod 最省事——它直接把返回的 JSON 解析成对象,连 ConvertFrom-Json 都省了。Windows 自带的 PowerShell 5.1 和 PowerShell 7 都支持下面这段。

定义查询函数,不传 IP 就查本机出口:

powershell
function Get-IpGeo {
    param(
        [string]$Ip   # 不填 = 查当前出口 IP
    )
    $url = if ([string]::IsNullOrWhiteSpace($Ip)) {
        'https://ip9.com.cn/get'
    } else {
        "https://ip9.com.cn/get?ip=$Ip"
    }
    $headers = @{ 'User-Agent' = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)' }
    try {
        $resp = Invoke-RestMethod -Uri $url -Headers $headers -TimeoutSec 8
        if ($resp.ret -ne 200) {
            Write-Warning "查询失败 ret=$($resp.ret)(400=非法IP)"
            return $null
        }
        $d = $resp.data
        [PSCustomObject]@{
            IP          = $d.ip
            Country     = $d.country
            CountryCode = $d.country_code
            Province    = $d.prov
            City        = $d.city
            ISP         = $d.isp
            Longitude   = $d.lng
            Latitude    = $d.lat
        }
    }
    catch {
        Write-Warning "请求失败: $($_.Exception.Message)"
        return $null
    }
}

用法:

powershell
Get-IpGeo                      # 查本机出口 IP 归属地
Get-IpGeo -Ip 223.5.5.5        # 查指定 IP
Get-IpGeo -Ip 2408:8000::1     # IPv6 一样查

单次查询会返回一个带 IP、国家、省份、城市、运营商的对象,控制台直接格式化显示。

四、批量查日志里的陌生 IP

批量场景记住一点:免费接口限速 60 次/分钟/IP,循环里加个间隔,别一口气把几百个 IP 打过去把自己限了。下面从日志文件里把所有 IPv4 提出来去重,逐个查询,每查一个歇 1.2 秒,结果导出 CSV:

powershell
# 从日志里提取全部 IPv4 并去重(正则按需调整)
$ips = Get-Content 'D:\logs\rdp-fail.log' |
    Select-String -Pattern '\b\d{1,3}(\.\d{1,3}){3}\b' -AllMatches |
    ForEach-Object { $_.Matches.Value } |
    Sort-Object -Unique

$result = foreach ($ip in $ips) {
    $geo = Get-IpGeo -Ip $ip
    if ($geo) { $geo }
    Start-Sleep -Milliseconds 1200   # 限速:60 次/分钟,留余量
}

$result | Export-Csv 'D:\logs\ips-geo.csv' -NoTypeInformation -Encoding UTF8

跑完打开 CSV,按国家或运营商一排序,哪些是海外机房扫进来的、哪些是国内各地 IP,一目了然。要把 CSV 里某个国家的 IP 批量加进防火墙,Import-Csv 读回来再喂给 New-NetFirewallRule 就行,这里不展开。

五、落地注意事项

  • 控制台中文乱码:PowerShell 5.1 的 Windows PowerShell 控制台默认代码页可能显示不了中文,先执行 chcp 65001 切到 UTF-8,或者干脆不管显示、直接看导出的 CSV(上面已经用 -Encoding UTF8)。脚本文件本身存成 UTF-8 with BOM,5.1 才不会把中文注释读乱。
  • 限速节奏:60 次/分钟是单 IP 额度。大批量查询把 Start-Sleep 间隔拉到 1.5 秒以上更稳;真有几万条要查,考虑分批或者换 VIP 额度,别硬怼免费接口。
  • 海外 IP 字段为空provcity 只有国内地址才有值,海外返回空字符串,脚本不用特殊处理,显示为空而已。
  • 查到的地区别当「人肉定位」:归属地是网络出口属性。日志里那些海外来源多半是扫端口的肉鸡或云主机,判断「要不要封」看地区和端口行为足够;但涉及追踪具体人,那得走正规调证流程,不是查归属地能解决的。
  • 依赖放前面:如果 Invoke-RestMethod 在你机器上因为 TLS 版本报错(老系统偶发),脚本开头加一句 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

总结

把上面函数存成 ipgeo.ps1,放服务器上随时 Import-Module 或者干脆复制进 profile,以后查 IP 归属地就是一条 Get-IpGeo -Ip xxx 的事;配合日志提取和导出 CSV,安全排查从「开网页一个个粘」变成「跑个脚本看表格」。Windows 运维和 Linux 用 curl 是同一个思路,只是工具换成 PowerShell 的原生 cmdlet。

接口用的 IP9 免费版,无需注册:GET https://ip9.com.cn/get 查当前出口 IP,?ip= 查指定 IP(IPv4/IPv6),返回国家、省市、运营商、经纬度等字段,60 次/分钟/IP。需要区县、IP 类型(家庭宽带/企业/机房)这类更细字段,看官网 VIP 说明:https://www.ip9.com.cn