param( [switch]$InstallVirtIO, [switch]$EnableAutomaticLogon, [switch]$NoPause ) $ErrorActionPreference = 'Stop' Set-StrictMode -Version Latest function Test-Administrator { $identity = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = [Security.Principal.WindowsPrincipal]::new($identity) return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } if (-not (Test-Administrator)) { if (-not $PSCommandPath) { throw 'Run this script from a PowerShell window opened as Administrator.' } $arguments = @('-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', "`"$PSCommandPath`"") foreach ($name in $PSBoundParameters.Keys) { $arguments += "-$name" } $elevated = Start-Process ` -FilePath 'powershell.exe' ` -ArgumentList $arguments ` -Verb RunAs ` -Wait ` -PassThru exit $elevated.ExitCode } function Install-VirtIOGuestTools { $installer = Get-ChildItem ` -Path (Get-PSDrive -PSProvider FileSystem).Root ` -Filter 'virtio-win-guest-tools.exe' ` -File ` -ErrorAction SilentlyContinue | Select-Object -First 1 if (-not $installer) { throw 'virtio-win-guest-tools.exe was not found on the attached media.' } $process = Start-Process ` -FilePath $installer.FullName ` -ArgumentList '/quiet', '/norestart' ` -Wait ` -PassThru if ($process.ExitCode -notin 0, 3010) { throw "VirtIO guest tools installer exited with code $($process.ExitCode)." } } function Install-OpenSSHServer { $capability = Get-WindowsCapability -Online -Name 'OpenSSH.Server*' | Select-Object -First 1 if (-not $capability) { throw 'The OpenSSH Server Windows capability was not found.' } if ($capability.State -ne 'Installed') { Add-WindowsCapability -Online -Name $capability.Name | Out-Null } Set-Service -Name 'sshd' -StartupType Automatic Start-Service -Name 'sshd' $rule = Get-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -ErrorAction SilentlyContinue if ($rule) { Set-NetFirewallRule ` -Name 'OpenSSH-Server-In-TCP' ` -Enabled True ` -Profile Private, Public } else { New-NetFirewallRule ` -Name 'OpenSSH-Server-In-TCP' ` -DisplayName 'OpenSSH SSH Server (sshd)' ` -Enabled True ` -Direction Inbound ` -Protocol TCP ` -Action Allow ` -LocalPort 22 ` -Profile Private, Public | Out-Null } } function Install-AdministratorAuthorizedKey { $authorizedKeys = Join-Path $env:ProgramData 'ssh\administrators_authorized_keys' $publicKey = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCwsF2ZDSHDaXM9BdDq3Vxkp6T+DJEakKaVZQJUEHexS34mbrxYAxmGBUPCrddfE01dS31kGS4XHVBa+wGUYodY+nPwnrfD1Q4phKVSzXr65K1Y/sCcjSiANBPWpv2Xd7IMOfLlrdLtmf5QcKWroIqO2LaIDGECwzUUHrfprgeaF9N0FGcmrgbmm23JUk+f6guRQ4br88L4rWIWEBvL9bTdwErNkdfsYE2F/U8aIFpMcVy2eJIOgy8ZjZvkGdm4r730YkTDL1VmAjiHH3/m2R1EOvwLzFhyWKoa4ULk/IQW+8iNnG42QEcaWRM+hMwlVdnNhPJP6WzS+fAEbibD3zM0q2X/4ex+cXRNOCd2/0KhnD2+3p1BM5QeFTzDappkk8W2meQkDE3hvTjtIQCzygFO6LNWtEEa7BTvvlMqF3CZWh88J9XiP750SjESe3Ge5o9A0T2hcJa+KZ1LxVEmNt4nD6E/OD4EymoaLIJZ1fH5ksSFjHzJ+mJouSVjc/H/VSE= guofang@GUOFANG-OFFICE' [IO.File]::WriteAllText( $authorizedKeys, $publicKey + [Environment]::NewLine, [Text.Encoding]::ASCII ) & icacls.exe ` $authorizedKeys ` '/inheritance:r' ` '/grant' ` '*S-1-5-32-544:F' ` '*S-1-5-18:F' if ($LASTEXITCODE -ne 0) { throw "icacls.exe exited with code $LASTEXITCODE." } } function Enable-AutomaticLogon { $winlogonPath = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' Set-ItemProperty -Path $winlogonPath -Name 'AutoAdminLogon' -Value '1' -Type String Set-ItemProperty -Path $winlogonPath -Name 'DefaultUserName' -Value 'guofang' -Type String Set-ItemProperty -Path $winlogonPath -Name 'DefaultPassword' -Value 'wang' -Type String Set-ItemProperty -Path $winlogonPath -Name 'DefaultDomainName' -Value $env:COMPUTERNAME -Type String Remove-ItemProperty -Path $winlogonPath -Name 'AutoLogonCount' -ErrorAction SilentlyContinue } $exitCode = 0 try { if ($InstallVirtIO) { Install-VirtIOGuestTools } Install-OpenSSHServer Install-AdministratorAuthorizedKey if ($EnableAutomaticLogon) { Enable-AutomaticLogon } Write-Host 'Done.' -ForegroundColor Green } catch { Write-Host "Failed: $($_.Exception.Message)" -ForegroundColor Red $exitCode = 1 } if (-not $NoPause) { Read-Host 'Press Enter to exit' | Out-Null } exit $exitCode