PowerShell编写Windows服务器的DDNS-ipv6客户端

复制下面这个代码保存成“ddnsv6.fm20.cn.ps1”然后运行

function Get-GUID() {
    # 指定注册表路径
    $path = "HKLM:\Software\Firadio"

    # 如果注册表路径不存在则创建
    if (-not (Test-Path $path)) {
        New-Item -Force -Path $path >$null
    }

    # 尝试获取注册表中的 "guid" 属性值
    $v = Get-ItemProperty -ErrorAction SilentlyContinue -Path $path -Name "g"
    if ($v) {
        return $v.g
    }

    # 如果 "guid" 属性不存在,则生成一个新的 GUID 并写入注册表
    $g = [System.Guid]::NewGuid().Guid
    Set-ItemProperty -Path $path -Name "g" -Value $g
    return $g
}

# 创建一个 UDP 客户端并发送数据
$udpClient = New-Object System.Net.Sockets.UdpClient([System.Net.Sockets.AddressFamily]::InterNetworkV6)
$data = Get-GUID
$msg = [Text.Encoding]::UTF8.GetBytes($data)

# 循环发送数据
while ($true) {
    $udpClient.Send($msg, $msg.Length, 'ddnsv6.fm20.cn', 12345)
    Start-Sleep -Seconds 1
}

# 关闭 UDP 客户端
$udpClient.Close()

但有些电脑运行后会提示错误

ddnsv6.fm20.cn.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
    + CategoryInfo          : SecurityError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnauthorizedAccess

所以下面我改成bat,确保大多数Windows系统都能正常能运行。
复制下面这个代码并保存成“ddnsv6.fm20.cn.bat”就能正常运行了

powershell -c "function Get-GUID(){$path=\"HKLM:\Software\Firadio\ddnsv6.fm20.cn\";if (-not (Test-Path $path)) {New-Item -Force -Path $path >$null;}$v=Get-ItemProperty -ErrorAction SilentlyContinue -Path $path -Name \"guid\";if ($v) {return $v.guid;}$guid=[System.Guid]::NewGuid().Guid;Set-ItemProperty -Path $path -Name \"guid\" -Value $guid;return $guid;}$udpClient=New-Object System.Net.Sockets.UdpClient([System.Net.Sockets.AddressFamily]::InterNetworkV6);$data=Get-GUID;$msg=[Text.Encoding]::UTF8.GetBytes($data);while($true){try{$ret=$udpClient.Send($msg,$msg.Length,'ddnsv6.fm20.cn',12345);}catch{Write-Host \"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') $_\"}Start-Sleep -Seconds 10;}$udpClient.Close();"

但是每次开机都要手动打开,显然不太合适,所以就设置成开机自动启动

但是schtasks限制了261字节,因此改成

powershell -c "function Get-GUID(){$path=\"HKLM:\Software\Firadio\";if (-not (Test-Path $path)) {New-Item -Force -Path $path >$null;}$v=Get-ItemProperty -ErrorAction SilentlyContinue -Path $path -Name \"g\";if ($v) {return $v.g;}$g=[System.Guid]::NewGuid().Guid;Set-ItemProperty -Path $path -Name \"g\" -Value $g;return $g;}Get-GUID;"
schtasks /end /tn "v6.fm20.cn"
schtasks /create /F /tn "v6.fm20.cn" /tr "powershell -c \"$c=New-Object Net.Sockets.UdpClient([Net.Sockets.AddressFamily]::InterNetworkV6);$v=gp -Pa \\\"HKLM:\SOFTWARE\Firadio\\\" -N \\\"g\\\";$m=[Text.Encoding]::UTF8.GetBytes($v.g);for(){$c.Send($m,$m.Length,\\\"v6.fm20.cn\\\",1);sleep 1}\"" /sc onstart /ru "SYSTEM"
schtasks /run /tn "v6.fm20.cn"

但是Guid可能会因为系统克隆而导致多台电脑相同的g值,因此改成获取MAC地址最为合适

powershell -c "$mac=(Get-NetAdapter -InterfaceIndex (Get-NetIPAddress -AddressFamily IPv6|Where-Object {$_.IPAddress -like '2*'} | Select-Object -First 1).InterfaceIndex).MacAddress;$path=\"HKLM:\Software\Firadio\";if (-not (Test-Path $path)) {New-Item -Force -Path $path >$null;};Set-ItemProperty -Path $path -Name \"g\" -Value $mac;"
schtasks /end /tn "v6.fm20.cn"
schtasks /create /F /tn "v6.fm20.cn" /tr "powershell -c \"$c=New-Object Net.Sockets.UdpClient([Net.Sockets.AddressFamily]::InterNetworkV6);for(){$v=gp -Pa \\\"HKLM:\SOFTWARE\Firadio\\\" -N \\\"g\\\";$m=[Text.Encoding]::UTF8.GetBytes($v.g);$c.Send($m,$m.Length,\\\"v6.fm20.cn\\\",1);sleep 1}\"" /sc onstart /ru "SYSTEM"
schtasks /run /tn "v6.fm20.cn"

但是3天后就关闭了,而且不小心杀了进程也不会再启动了。所以改成每分钟都运行,但如果已经运行的就不会重复运行多个。

@ECHO OFF
powershell -c "$mac=(Get-NetAdapter -InterfaceIndex (Get-NetIPAddress -AddressFamily IPv6|Where-Object {$_.IPAddress -like '2*'} | Select-Object -First 1).InterfaceIndex).MacAddress;$path=\"HKLM:\Software\Firadio\";if (-not (Test-Path $path)) {New-Item -Force -Path $path >$null;};Set-ItemProperty -Path $path -Name \"g\" -Value $mac;"
schtasks /end /tn "v6.fm20.cn"
schtasks /create /F /TN "v6.fm20.cn" /RU "SYSTEM" /SC MINUTE /MO 1 /TR "powershell -c \"$c=New-Object Net.Sockets.UdpClient([Net.Sockets.AddressFamily]::InterNetworkV6);for(){$v=gp -Pa \\\"HKLM:\SOFTWARE\Firadio\\\" -N \\\"g\\\";$m=[Text.Encoding]::UTF8.GetBytes($v.g);$c.Send($m,$m.Length,\\\"v6.fm20.cn\\\",1);sleep 1}\""
schtasks /run /tn "v6.fm20.cn"
PAUSE
posted on 2024-01-27 17:47  项希盛  阅读(14)  评论(0编辑  收藏  举报