设为首页收藏本站

 找回密码
 立即注册
搜索
查看: 72|回复: 3

修改体系安装时间

[复制链接]
累计签到:7 天
连续签到:1 天
灌水成绩
6
8
1285
主题
帖子
积分

等级头衔

ID : 632

测量学徒

积分成就 测量币 : 1285
在线时间 : 0 小时
注册时间 : 2026-4-6
最后登录 : 2026-5-6

勋章
UID勋章测量学徒测量员
联系方式
发表于 昨天 18:31 来自手机 | 显示全部楼层 |阅读模式 IP:香港
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
累计签到:6 天
连续签到:1 天
灌水成绩
3
82
625
主题
帖子
积分

等级头衔

ID : 811

测量学徒

积分成就 测量币 : 625
在线时间 : 0 小时
注册时间 : 2026-4-6
最后登录 : 2026-5-6

勋章
UID勋章测量学徒测量员
联系方式
发表于 昨天 18:45 | 显示全部楼层 IP:香港
有什么作用?谢谢
回复

使用道具 举报

累计签到:7 天
连续签到:2 天
灌水成绩
2
90
494
主题
帖子
积分

等级头衔

ID : 898

测量员

积分成就 测量币 : 494
在线时间 : 0 小时
注册时间 : 2026-4-6
最后登录 : 2026-5-7

勋章
UID勋章测量学徒测量员
联系方式
发表于 昨天 18:56 | 显示全部楼层 IP:香港
学习了
回复

使用道具 举报

累计签到:5 天
连续签到:1 天
灌水成绩
2
88
370
主题
帖子
积分

等级头衔

ID : 845

测量员

积分成就 测量币 : 370
在线时间 : 0 小时
注册时间 : 2026-4-6
最后登录 : 2026-5-7

勋章
UID勋章测量学徒测量员
联系方式
发表于 昨天 19:02 | 显示全部楼层 IP:香港
不错,试试
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|精密测量技术论坛 ( 桂ICP备2026007449号-1 )|网站地图

GMT+8, 2026-5-7 04:35 , Processed in 0.105602 second(s), 31 queries .

快速回复 返回顶部 返回列表