累计签到:7 天 连续签到:1 天
|
AI写的联网后自动从ntp获取当前时间,并且修改系统安装时间为当前时间
- # ========== 修改当前进程实行策略 ==========
- try {
- Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force -ErrorAction Stop
- Write-Host "当前进程实行策略已临时设置为 Bypass" -ForegroundColor Green
- } catch {
- Write-Host "错误:无法修改当前进程的实行策略!" -ForegroundColor Red
- Write-Host "缘故原由: $($_.Exception.Message)" -ForegroundColor Red
- Write-Host "请手动以管理员身份运行 PowerShell,然后实行以下命令:" -ForegroundColor Yellow
- Write-Host " Set-ExecutionPolicy -Scope Process Bypass" -ForegroundColor White
- Write-Host " cd `"$PSScriptRoot`""
- Write-Host " .\`"$([System.IO.Path]::GetFileName($PSCommandPath))`""
- Write-Host "按恣意键退出..."
- $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
- exit 1
- }
- # ========== 防火墙 NTP 端口放行(出站+入站) ==========
- function Ensure-NTPFirewallRules {
- Write-Host "正在配置防火墙放行全部 NTP 规则(UDP 123)..." -ForegroundColor White
- $rules = @(
- @{
- Name = "NTP Client Outbound (UDP 123)"
- Description = "允许 NTP 客户端通过 UDP 123 端口出站同步时间"
- Direction = "Outbound"
- LocalPort = "Any"
- RemotePort = "123"
- },
- @{
- Name = "NTP Client Inbound (UDP 123)"
- Description = "允许 NTP 客户端接收 UDP 123 端口的应答数据"
- Direction = "Inbound"
- LocalPort = "123"
- RemotePort = "Any"
- }
- )
- $allOk = $true
- foreach ($rule in $rules) {
- $ruleName = $rule.Name
- $existing = Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue
- if ($existing) {
- if ($existing.Enabled -eq 'True' -and $existing.Action -eq 'Allow') {
- Write-Host "规则已存在并精确启用: $ruleName" -ForegroundColor Green
- } else {
- Write-Host "规则存在但状态异常,正在修复: $ruleName" -ForegroundColor Yellow
- try {
- Set-NetFirewallRule -DisplayName $ruleName -Enabled True -Action Allow -ErrorAction Stop
- Write-Host "规则已修复。" -ForegroundColor Green
- } catch {
- Write-Host "修复失败: $($_.Exception.Message)" -ForegroundColor Red
- $allOk = $false
- }
- }
- continue
- }
- try {
- Write-Host " → 正在创建规则: $ruleName" -ForegroundColor Yellow
- New-NetFirewallRule -DisplayName $ruleName `
- -Description $rule.Description `
- -Direction $rule.Direction `
- -Protocol UDP `
- -LocalPort $rule.LocalPort `
- -RemotePort $rule.RemotePort `
- -Action Allow `
- -Enabled True `
- -Profile Any `
- -ErrorAction Stop | Out-Null
- Write-Host "规则已创建并启用。" -ForegroundColor Green
- } catch {
- Write-Host "创建失败: $($_.Exception.Message)" -ForegroundColor Red
- $allOk = $false
- }
- }
- if ($allOk) {
- Write-Host "全部 NTP 防火墙规则已精确配置。" -ForegroundColor Green
- } else {
- Write-Host "部分规则配置失败,但仍将继承实验同步时间。" -ForegroundColor Yellow
- }
- return $allOk
- }
- # ========== NTP 同步函数(单次哀求,带重试,已修复资源泄漏) ==========
- function Sync-TimeFromNTP {
- param([string]$server, [int]$port = 123, [int]$retries = 3)
- $attempt = 0
- while ($attempt -lt $retries) {
- $client = $null
- try {
- $ntpData = New-Object byte[] 48
- $ntpData[0] = 0x1B # LI=0, VN=3, Mode=3
- $client = New-Object System.Net.Sockets.UdpClient
- $client.Connect($server, $port)
- $null = $client.Send($ntpData, $ntpData.Length)
- $client.Client.ReceiveTimeout = 5000 # 5 秒超时
- $remoteEP = New-Object System.Net.IPEndPoint ([IPAddress]::Any, 0)
- $receivedData = $client.Receive([ref]$remoteEP)
- # 剖析 Transmit Timestamp(第40-47字节)
- $intPart = [UInt64]0
- $fracPart = [UInt64]0
- for ($i = 0; $i -lt 4; $i++) {
- $intPart = ($intPart -shl 8) -bor $receivedData[40 + $i]
- }
- for ($i = 4; $i -lt 8; $i++) {
- $fracPart = ($fracPart -shl 8) -bor $receivedData[40 + $i]
- }
- $ntpSeconds = [double]$intPart + ([double]$fracPart / 4294967296.0)
- $unixTimestamp = $ntpSeconds - 2208988800.0
- if ($unixTimestamp -le 0) {
- throw "NTP 返回时间戳无效"
- }
- $utcTime = ([DateTime]'1970-01-01 00:00:00').AddSeconds($unixTimestamp)
- return $utcTime
- }
- catch {
- $attempt++
- Write-Host " [$server] 第 $attempt 次实验失败: $($_.Exception.Message.TrimEnd())" -ForegroundColor DarkGray
- if ($attempt -lt $retries) { Start-Sleep -Milliseconds 500 }
- }
- finally {
- if ($client) {
- try { $client.Close() } catch {}
- try { $client.Dispose() } catch {}
- }
- }
- }
- return $null
- }
- # ========== 设置系统当地时间(kernel32 调用) ==========
- Add-Type -TypeDefinition @"
- using System;
- using System.Runtime.InteropServices;
- public class WinAPI {
- [StructLayout(LayoutKind.Sequential)]
- public struct SYSTEMTIME {
- public UInt16 wYear;
- public UInt16 wMonth;
- public UInt16 wDayOfWeek;
- public UInt16 wDay;
- public UInt16 wHour;
- public UInt16 wMinute;
- public UInt16 wSecond;
- public UInt16 wMilliseconds;
- }
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern bool SetLocalTime(ref SYSTEMTIME st);
- }
- "@
- function Set-LocalTime {
- param([DateTime]$localTime)
- $st = New-Object WinAPI+SYSTEMTIME
- $st.wYear = $localTime.Year
- $st.wMonth = $localTime.Month
- $st.wDay = $localTime.Day
- $st.wDayOfWeek = [System.UInt16]$localTime.DayOfWeek
- $st.wHour = $localTime.Hour
- $st.wMinute = $localTime.Minute
- $st.wSecond = $localTime.Second
- $st.wMilliseconds = $localTime.Millisecond
- return [WinAPI]::SetLocalTime([ref]$st)
- }
- # ========== 将 UTC DateTime 转换为 18 位 LDAP 时间戳(已修复精度问题) ==========
- function ConvertTo-LDAPTimestamp {
- param([DateTime]$DateTime)
- $utcTime = $DateTime.ToUniversalTime()
- Write-Host "计算 LDAP 时间戳基于 UTC: $($utcTime.ToString('yyyy-MM-dd HH:mm:ss'))"
- $epoch = New-Object DateTime(1601, 1, 1, 0, 0, 0, [DateTimeKind]::Utc)
- $ticks = $utcTime.Ticks - $epoch.Ticks
- $highPart = [int64]($ticks / 10000000)
- $lowPart = $ticks % 10000000
- $ldapString = $highPart.ToString() + $lowPart.ToString("0000000")
- return $ldapString
- }
- # ========== 主流程 ==========
- Write-Host "`n========== 防火墙配置 ==========" -ForegroundColor Cyan
- $firewallOk = Ensure-NTPFirewallRules
- if (-not $firewallOk) {
- Write-Host "部分防火墙规则未精确配置,但仍将继承实验同步..." -ForegroundColor Yellow
- }
- $ntpServers = @(
- "ntp.ntsc.ac.cn",
- "time.aliyun.com",
- "ntp.tencent.com",
- "ntp1.aliyun.com",
- "cn.pool.ntp.org",
- "edu.ntp.org.cn"
- )
- $timeService = Get-Service -Name w32time -ErrorAction SilentlyContinue
- $wasRunning = $false
- if ($timeService -and $timeService.Status -eq 'Running') {
- Write-Host "正在制止 w32time 服务以释放 UDP 123 端口..." -ForegroundColor Yellow
- Stop-Service w32time -Force -ErrorAction SilentlyContinue
- Start-Sleep -Milliseconds 500
- $wasRunning = $true
- }
- $synced = $false
- $utcResult = $null
- try {
- Write-Host "`n========== NTP 时间同步 ==========" -ForegroundColor Cyan
- foreach ($server in $ntpServers) {
- Write-Host "正在实验从 $server 获取时间..." -ForegroundColor White
- $utcResult = Sync-TimeFromNTP -server $server
- if ($utcResult) {
- $localTime = $utcResult.ToLocalTime()
- if (Set-LocalTime -localTime $localTime) {
- $synced = $true
- Write-Host "时间同步乐成(泉源:$server)" -ForegroundColor Green
- break
- } else {
- Write-Host "设置系统时间失败,请确认管理员权限。" -ForegroundColor Red
- break
- }
- } else {
- Write-Host "无法从 $server 获取有效时间" -ForegroundColor Yellow
- }
- }
- }
- finally {
- if ($wasRunning) {
- Write-Host "正在恢复 w32time 服务..." -ForegroundColor Yellow
- Start-Service w32time -ErrorAction SilentlyContinue
- }
- }
- if (-not $synced) {
- Write-Host "`n全部 NTP 服务器均未能返回有效时间!" -ForegroundColor Red
- Write-Host "请查抄网络连接后重试。" -ForegroundColor DarkYellow
- Write-Host "按恣意键退出..."
- $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
- exit 1
- }
- $utcNow = [DateTime]::UtcNow
- $localNow = $utcNow.ToLocalTime()
- $unixTimestamp = [int64]($utcNow - [DateTime]::new(1970,1,1,0,0,0,[DateTimeKind]::Utc)).TotalSeconds
- $ntFileTime = $utcNow.ToFileTime()
- Write-Host "`n同步后的时间:" -ForegroundColor Cyan
- Write-Host " 当地时间 : $($localNow.ToString('yyyy-MM-dd HH:mm:ss'))"
- Write-Host " Unix 时间戳 : $unixTimestamp"
- Write-Host " NT 文件时间 : $ntFileTime"
- $regPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
- try {
- if ($unixTimestamp -lt 0 -or $unixTimestamp -gt [UInt32]::MaxValue) {
- throw "Unix 时间戳超出 REG_DWORD 范围"
- }
- New-ItemProperty -Path $regPath -Name "InstallDate" -Value ([UInt32]$unixTimestamp) -PropertyType DWord -Force | Out-Null
- Write-Host "InstallDate (REG_DWORD) 写入乐成" -ForegroundColor Green
- $ldapTimestampString = ConvertTo-LDAPTimestamp -DateTime $utcNow
- if ([string]::IsNullOrEmpty($ldapTimestampString)) {
- throw "LDAP 时间戳计算结果为空"
- }
- $ldapTimestamp = [UInt64]$ldapTimestampString
- New-ItemProperty -Path $regPath -Name "InstallTime" -Value $ldapTimestamp -PropertyType QWord -Force | Out-Null
- Write-Host "InstallTime (REG_QWORD) 写入乐成: $ldapTimestampString" -ForegroundColor Green
- Write-Host "`n系统安装时间已乐成更新!" -ForegroundColor Cyan
- }
- catch {
- Write-Host "注册表写入失败:$($_.Exception.Message)" -ForegroundColor Red
- }
- Write-Host "`n按恣意键退出..."$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')

不知道为啥,直接powershell运行,临时运行策略不生效,使用Ps1_To_Exe转成exe后又没问题,用的是administrator账号测试的,求大佬指点 |
精密测量技术论坛免责声明
重要声明:以上内容仅代表该作者观点,不代表本站精密测量技术论坛立场。
如有涉及侵权请尽快告知,我们将会在第一时间处理。作者原创内容未经允许不得转载!
站长联系邮箱:1339305021@qq.com
站长联系微信:dddnnbbb
|