Skip to content

Instantly share code, notes, and snippets.

@hunandy14
Last active October 16, 2024 04:52
Show Gist options
  • Save hunandy14/15f2e3bf5b1a328df022a3a9f4f8ccd1 to your computer and use it in GitHub Desktop.
Save hunandy14/15f2e3bf5b1a328df022a3a9f4f8ccd1 to your computer and use it in GitHub Desktop.
自動爬蟲抓取最新版本OpenSSH並安裝
# 獲取最新版本OpenSSHUrl
function Get-OpenSSHAsset {
param (
[Parameter(Position = 0, ParameterSetName = "")]
[ValidateSet(
'OpenSSH-Win32.zip',
'OpenSSH-Win64.zip',
'OpenSSH-Win32.msi',
'OpenSSH-Win64.msi'
)]
[string] $AssetName = 'OpenSSH-Win64.zip'
)
# 設定 API URL
$url = "https://api.github.com/repos/PowerShell/Win32-OpenSSH/releases/latest"
# 使用 Invoke-RestMethod 獲取 API 返回的資料
$response = Invoke-RestMethod -Uri $url
# 根據 $AssetName 參數調整過濾條件
if ($AssetName -match ".msi$") {
$filter = "^$($AssetName -replace ".msi$", "-v.*.msi")$"
} elseif ($AssetName -match ".zip$") { $filter = "^$AssetName$" }
# 從 assets 中尋找指定的文件名
return $response.assets | Where-Object { $_.name -match $filter }
} # Get-OpenSSHAsset 'OpenSSH-Win64.zip'
# 安裝OpenSSH
function Install-OpenSSH {
param (
# 安裝路徑
[Parameter(Position = 0, ParameterSetName = "")]
[string] $Path = 'C:\Program Files',
# 從線上下載
[Parameter(ParameterSetName = "")]
[switch] $IncludeServer,
[switch] $OpenFirewall,
[switch] $Force
)
[IO.Directory]::SetCurrentDirectory(((Get-Location -PSProvider FileSystem).ProviderPath))
$Path = [IO.Path]::GetFullPath($Path)
# 爬取最新版本的URL
$asset = Get-OpenSSHAsset 'OpenSSH-Win64.zip'
if ($asset) {
$sshZipName = $asset.name
$sshUrl = $asset.browser_download_url
} else {
$sshZipName = 'OpenSSH-Win64.zip'
$sshUrl = 'https://github.com/PowerShell/Win32-OpenSSH/releases/download/v9.4.0.0p1-Beta/OpenSSH-Win64.zip'
}
# 檢查安裝目錄
if ((Test-Path $Path) -and (Get-ChildItem -Path $Path)) {
if ($Force) {
$scriptPath = Join-Path (Split-Path (Get-Command sshd).Source) 'uninstall-sshd.ps1'
if (Test-Path $scriptPath) {
Write-Host "Detected that the directory '$Path' is not empty. Attempting to remove the old version of OpenSSH..." -ForegroundColor Yellow
Powershell.exe -ExecutionPolicy Bypass -File $scriptPath
if ($LASTEXITCODE -ne 0) { return }
}
} else {
Write-Error "Directory '$Path' is not empty. Use the -Force option to force the installation." -ErrorAction Stop
}
}
# 下載Zip檔案
$sshZipPath = Join-Path $env:TEMP $sshZipName
(New-Object Net.WebClient).DownloadFile($sshUrl, $sshZipPath)
# 解壓縮並安裝到目標位置
[String] $sshbin = Join-Path $Path ([IO.Path]::GetFileNameWithoutExtension($sshZipName))
Expand-Archive $sshZipPath $Path -Force -ErrorAction Stop
if (Test-Path -Path $sshbin) {
try {
Copy-Item -Path $sshbin\* -Destination $Path -Recurse -Force
} catch { throw } finally {
Remove-Item -Path $sshbin -Recurse -Force
}
$sshbin = $Path
}
# 添加環境變數
$currEnvPath = [Environment]::GetEnvironmentVariable("Path", 'Machine')
if (-not $currEnvPath.Split(';').Contains($sshbin)) {
$newEnvPath = $sshbin + ";" + $currEnvPath
[Environment]::SetEnvironmentVariable("Path", $newEnvPath, 'Machine')
} else {
Write-Host "The path $sshbin is already in the system PATH variable." -ForegroundColor Green
}; $env:Path = ([Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [Environment]::GetEnvironmentVariable("Path", "User"))
# 驗證 SSH 是否被追加
try { Get-Command ssh, sshd -EA 1; Write-Host "" } catch {
Write-Error "Error:: The SSH command was not found, terminating the installation. The environment variable may not have been correctly added, or the path is incorrect" -ErrorAction Stop
}
# 安裝伺服器端
if ($IncludeServer) {
# 安裝sshd
try {
Get-Service sshd -ErrorAction Stop | Out-Null
Write-Host "sshd service already exists. Skipping installation." -ForegroundColor Green
} catch {
$sshInstaller = Join-Path $sshbin 'install-sshd.ps1'
Powershell.exe -ExecutionPolicy Bypass -File $sshInstaller
if ($LASTEXITCODE -ne 0) { return }
}
# 啟用sshd
try {
Start-Service sshd -ErrorAction Stop
Set-Service sshd -StartupType 'Automatic'
} catch {
Write-Error "Failed to install or start the sshd service." -ErrorAction Stop
}
# 啟用防火牆
if ($OpenFirewall) {
if (!(Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue | Select-Object Name, Enabled)) {
Write-Host "Firewall Rule 'OpenSSH-Server-In-TCP' does not exist, creating it..."
New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
} else {
Write-Host "Firewall rule 'OpenSSH-Server-In-TCP' has been created and exists." -ForegroundColor DarkGreen
}
}
}
} # Install-OpenSSH 'C:\Program Files\OpenSSH' -IncludeServer -OpenFirewall -Force
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment