199 lines
7.4 KiB
PowerShell
199 lines
7.4 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Downloads ConfigWinRM.ps1 and ConfigWinRM.xml to C:\WinRM and optionally sets the
|
|
Zabbix Proxy IP address as the WinRM firewall trusted host.
|
|
|
|
.DESCRIPTION
|
|
Downloads ConfigWinRM.ps1 and ConfigWinRM.xml from the internal Git server
|
|
(git.totalservice.cz, WindowsServer repo) into C:\WinRM, creating that folder if it
|
|
does not already exist. After the download, it asks for the Zabbix Proxy IP
|
|
address: if one is entered, it is written into the <FWWinRMTrustedHosts> element of
|
|
the downloaded ConfigWinRM.xml; if the prompt is left empty (Enter only),
|
|
ConfigWinRM.xml is left unchanged. The IP address can also be supplied directly via
|
|
the -ZabbixProxyIPAddress parameter to run the script non-interactively.
|
|
|
|
.PARAMETER ZabbixProxyIPAddress
|
|
Zabbix Proxy IP address to allow through the WinRM firewall rule
|
|
(FWWinRMTrustedHosts in ConfigWinRM.xml). Omit this parameter to be prompted
|
|
interactively (or to fall back to $env:ZabbixProxyIPAddress if that is set); pass
|
|
an empty string to skip the prompt and leave the existing value in ConfigWinRM.xml
|
|
unchanged.
|
|
|
|
.EXAMPLE
|
|
PS> .\Download-WinRMConfigScript.ps1
|
|
Downloads both files to C:\WinRM and interactively prompts for the Zabbix Proxy IP
|
|
address.
|
|
|
|
.EXAMPLE
|
|
PS> .\Download-WinRMConfigScript.ps1 -ZabbixProxyIPAddress '192.168.10.50'
|
|
Downloads both files and sets FWWinRMTrustedHosts to 192.168.10.50 without prompting.
|
|
|
|
.EXAMPLE
|
|
PS> irm https://s.tslab.cz/ZBXWinRM | iex
|
|
Shortest way to run the script directly from the repo without saving it locally
|
|
first; prompts interactively for the Zabbix Proxy IP address.
|
|
|
|
.NOTES
|
|
Author: Petr Štěpán
|
|
Created: 2026-07-21
|
|
Version: 1.2.0
|
|
Changelog:
|
|
1.0.0 - Initial version
|
|
1.1.0 - Added $env:ZabbixProxyIPAddress fallback so a plain "irm | iex"
|
|
one-liner can supply the IP address without "& { ... } -Param" wrapping
|
|
1.2.0 - Only call exit when running as a real .ps1 file, not when run via
|
|
"irm | iex" - exit would otherwise close the caller's PowerShell window
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $false, HelpMessage = 'Zabbix Proxy IP address to allow through the WinRM firewall rule. Leave empty to keep the existing value.')]
|
|
[string]
|
|
$ZabbixProxyIPAddress
|
|
)
|
|
|
|
# --- Safety preamble -------------------------------------------------------
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
# Older Windows Server releases don't enable TLS 1.2 by default, which would make the
|
|
# download below fail silently against a TLS-1.2-only server.
|
|
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
|
|
|
|
$SourceBaseUri = 'https://git.totalservice.cz/PSScripts/WindowsServer/raw/branch/main/ConfigWinRMForZabbix'
|
|
$DestinationPath = 'C:\WinRM'
|
|
$ScriptFile = Join-Path -Path $DestinationPath -ChildPath 'ConfigWinRM.ps1'
|
|
$ConfigFile = Join-Path -Path $DestinationPath -ChildPath 'ConfigWinRM.xml'
|
|
|
|
# --- Functions ---------------------------------------------------------
|
|
|
|
function Invoke-RemoteFileDownload {
|
|
<#
|
|
.SYNOPSIS
|
|
Downloads a single file from a URI to a local path.
|
|
.PARAMETER Uri
|
|
Source URI to download from.
|
|
.PARAMETER OutFile
|
|
Local destination file path.
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]
|
|
$Uri,
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]
|
|
$OutFile
|
|
)
|
|
|
|
try {
|
|
Invoke-WebRequest -Uri $Uri -OutFile $OutFile -UseBasicParsing
|
|
Write-Host "Downloaded '$Uri' to '$OutFile'."
|
|
}
|
|
catch {
|
|
Write-Error "Failed to download '$Uri' to '$OutFile': $_"
|
|
throw
|
|
}
|
|
}
|
|
|
|
function Update-WinRMTrustedHostConfig {
|
|
<#
|
|
.SYNOPSIS
|
|
Sets the <FWWinRMTrustedHosts> element of a ConfigWinRM.xml file.
|
|
.PARAMETER Path
|
|
Path to the ConfigWinRM.xml file to update.
|
|
.PARAMETER TrustedHost
|
|
Value to write into <FWWinRMTrustedHosts>.
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[ValidateScript({ Test-Path -Path $_ -PathType Leaf })]
|
|
[string]
|
|
$Path,
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]
|
|
$TrustedHost
|
|
)
|
|
|
|
try {
|
|
# PreserveWhitespace keeps the original file's indentation/comments intact -
|
|
# without it, XmlDocument.Save() would reformat the whole file.
|
|
$xml = New-Object -TypeName System.Xml.XmlDocument
|
|
$xml.PreserveWhitespace = $true
|
|
$xml.Load($Path)
|
|
|
|
$node = $xml.ConfigWinRM.Options.FWWinRMTrustedHosts
|
|
if ($null -eq $node) {
|
|
throw "Element <FWWinRMTrustedHosts> was not found in '$Path'."
|
|
}
|
|
|
|
$xml.ConfigWinRM.Options.FWWinRMTrustedHosts = $TrustedHost
|
|
$xml.Save($Path)
|
|
Write-Host "FWWinRMTrustedHosts set to '$TrustedHost' in '$Path'."
|
|
}
|
|
catch {
|
|
Write-Error "Failed to update '$Path': $_"
|
|
throw
|
|
}
|
|
}
|
|
|
|
# --- Main --------------------------------------------------------------
|
|
try {
|
|
if (-not (Test-Path -Path $DestinationPath)) {
|
|
New-Item -Path $DestinationPath -ItemType Directory -Force | Out-Null
|
|
Write-Host "Created directory '$DestinationPath'."
|
|
}
|
|
|
|
Invoke-RemoteFileDownload -Uri "$SourceBaseUri/ConfigWinRM.ps1" -OutFile $ScriptFile
|
|
Invoke-RemoteFileDownload -Uri "$SourceBaseUri/ConfigWinRM.xml" -OutFile $ConfigFile
|
|
|
|
# Only fall back to the environment variable / prompt when the caller did not pass
|
|
# the parameter at all - an explicit empty string ("") means "skip the prompt,
|
|
# leave ConfigWinRM.xml unchanged". $env:ZabbixProxyIPAddress lets a plain
|
|
# "irm <url> | iex" one-liner supply a value without needing "& { ... } -Param" -
|
|
# piping into iex runs the downloaded param() block as a plain statement with no
|
|
# bound arguments, so -ZabbixProxyIPAddress itself can only be set that way when
|
|
# the script is invoked as a real command (locally or via "& { ... }").
|
|
if (-not $PSBoundParameters.ContainsKey('ZabbixProxyIPAddress')) {
|
|
if ($env:ZabbixProxyIPAddress) {
|
|
$ZabbixProxyIPAddress = $env:ZabbixProxyIPAddress
|
|
}
|
|
else {
|
|
$ZabbixProxyIPAddress = Read-Host -Prompt 'Enter Zabbix Proxy IP address (press Enter to keep the current value)'
|
|
}
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($ZabbixProxyIPAddress)) {
|
|
Write-Host 'No Zabbix Proxy IP address provided - ConfigWinRM.xml left unchanged.'
|
|
}
|
|
else {
|
|
$parsedIp = $null
|
|
if (-not [System.Net.IPAddress]::TryParse($ZabbixProxyIPAddress, [ref] $parsedIp)) {
|
|
throw "'$ZabbixProxyIPAddress' is not a valid IP address."
|
|
}
|
|
|
|
Update-WinRMTrustedHostConfig -Path $ConfigFile -TrustedHost $ZabbixProxyIPAddress
|
|
}
|
|
}
|
|
catch {
|
|
Write-Error "Script failed: $_"
|
|
# $MyInvocation.MyCommand.Path is only set when this runs as an actual .ps1 file.
|
|
# When run via "irm <url> | iex" there is no backing file - the code executes in
|
|
# the caller's own session, so calling exit here would close their whole
|
|
# PowerShell window instead of just ending this script.
|
|
if ($MyInvocation.MyCommand.Path) {
|
|
exit 1
|
|
}
|
|
return
|
|
}
|
|
|
|
if ($MyInvocation.MyCommand.Path) {
|
|
exit 0
|
|
}
|