工作機升級後,64G RAM 配上 7GB/s 高速讀寫 SSD,建 VM 跟喝水一樣,以前建 VM 灌 Windows 通常要泡杯茶慢慢等,現在兩三分鐘搞定。裝機速度變快,其他沒效率的地方就現形了。

像是 VM 需要加入測試網域,裝機後需手動改固定 IP、設定 DNS、更改電腦名稱,嚴格說來操作不算複雜,滑幾下滑鼠敲敲打打就可以解決,但連做幾台有點厭煩,便想著將它指令化,打算用 PowerShell 搞定,順便練個功。

局勢發展至今,當然得快點適應跟 ChatGPT、Copliot 一起 Pair Programming 的生活。伴隨 AI 工具噴出一串串正確率 85% 的程式碼,常讓老碼農天人交戰,我該花時間去查 API 或指令的完整說明?還是不求甚解到底,有錯就叫 ChatGPT 改,徹底落實「伸手牌」,這行為不就是常被社群唾棄只想要答案的小白?該怎麼抓平衡點,我也還在模索,目前的原則是「只讓 AI 寫我已經知道怎麼寫的部分」,若 AI 給了沒看過的寫法或 API,就花點時間查資料了解,避免程式裡有自己不懂的程式碼。
(講到這個,剛好有網友提到有人只會 jQuery 完全不懂 JavaScript,沒有 AI 就不會寫程式的開發人員應該也快出現了)

最後完成程式如下:

# 取得使用中的網路介面卡名稱
$activeNetNames = Get-NetAdapter | Where-Object {$_.Status -eq "Up"}  | Select-Object -ExpandProperty Name

# 取得現有IP設定
$idx = 0
$ipConfigs = Get-NetIPConfiguration | Where-Object { $activeNetNames.Contains($_.InterfaceAlias) } | ForEach-Object {
    New-Object PSObject -Property @{
        Idx = $idx++
        InterfaceAlias = $_.InterfaceAlias
        InterfaceIndex = $_.InterfaceIndex
        IPAddress = $_.IPv4Address.IPAddress
        SubnetPrefix = $_.IPv4Address.PrefixLength
        Gateway = ($_.IPv4DefaultGateway).NextHop
        DNSServer = ($_.DnsServer | Where-Object { $_.AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetwork }).ServerAddresses -join ","
    }
}
Write-Host "選擇網卡設定 IP" -ForegroundColor Yellow
Write-Host
$ipConfigs | ForEach-Object {
    Write-Host "  $($_.Idx). 網卡名稱: $($_.InterfaceAlias) IP=$($_.IPAddress)/$($_.SubnetMask) Gateway=$($_.Gateway) DNS=$($_.DNSServer)"
}
Write-Host
if ($idx -eq 1) {
    $selectedIdx = 0
} else {
    $selectedIdx = Read-Host "請輸入要設定網卡編號 [0-$($idx - 1)]"
    # 將輸入的字串轉成數字,若非數字則傳回 -1
    if (-not [regex]::IsMatch($selectedIdx, '^\d+$') -or [int]$selectedIdx -lt 0 -or [int]$selectedIdx -ge $idx) {
        Write-Host "輸入錯誤"
        exit
    }
}
$ipConf = $ipConfigs[$selectedIdx]

# 取得網卡現有 IP、子網路遮罩、預設閘道、DNS
$defIpInfo = if ($ipConf.IPAddress) { $ipConf.IPAddress + '/' + $ipConf.SubnetPrefix } else { '192.168.1.1/24' }
$defGateway = if ($ipConf.Gateway) { $ipConf.Gateway } else { '192.168.1.254' }
$defDns = if ($ipConf.DnsServer) { $ipConf.DnsServer } else { '8.8.8.8' }
do {
    $ipInfo = Read-Host "請輸入 IP 地址及子網路遮罩 (ex:$defIpInfo)" 
} while ($ipInfo -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,2}$' -eq $false)
$ip = $ipInfo.Split('/')[0]
$subnetPfx = $ipInfo.Split('/')[1]
do {
    $gateway = Read-Host "請輸入預設閘道器 IP (ex:$defGateway)" 
} while ($gateway -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$' -eq $false)
do {
    $dns = Read-Host "請輸入 DNS 伺服器 IP (ex:$defDns)" 
} while ($dns -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$' -eq $false)

# 設定網卡 IP
if ($ipConf.IPAddress) { # 若已有 IP 則先移除
    Remove-NetIPAddress -InterfaceIndex $ipConf.InterfaceIndex -IPAddress $ipConf.IPAddress -Confirm:$false
}
if ($ipconf.Gateway) { # 若已有預設閘道器則先移除
    Remove-NetRoute -InterfaceIndex $ipConf.InterfaceIndex -NextHop $ipConf.Gateway -Confirm:$false
}
New-NetIPAddress -InterfaceIndex $ipConf.InterfaceIndex -AddressFamily IPv4 -IPAddress $ip -PrefixLength $subnetPfx -DefaultGateway $gateway -Confirm:$false | Out-Null

# 設定 DNS
Set-DnsClientServerAddress -InterfaceAlias $ipConf.InterfaceAlias -ServerAddresses $dns -Confirm:$false

# 修改電腦名稱
if ((Read-Host "目前電腦名稱為$($env:COMPUTERNAME),是否要修改? (Y/N)") -ieq 'y') {
    $newName = Read-Host "請輸入新電腦名稱"
    if ((Read-Host "確定要更名為[$newName]並重新開機 (Y/N)") -ieq 'y') {
        Rename-Computer -NewName $newName -Restart
    } 
}

實測 OK。

Example of using PowerShell to set IP, gateway, DNS and rename computer.


Comments

Be the first to post a comment

Post a comment