<# .SYNOPSIS Installs ZeroTier .DESCRIPTION Install ZeroTier and join/configure ZeroTier network .EXAMPLE ./InstallZeroTier.ps1 -NetworkID [Network ID] ./InstallZeroTier.ps1 -NetworkID [Network ID] -Token [API Token] -Headless .NOTES Requires PowerShell 7 or higher (installed if missing) when using the $Token parameter. A UAC prompt will appear during install if -Headless is not used. CREDIT: https://gist.github.com/wise-io #> param ( [Parameter(Mandatory = $true)] [string]$NetworkID, # ZeroTier Network ID [string]$Token, # ZeroTier API Token [switch]$Headless, # Run msi in headless mode [Alias('AllowDNS')] [switch]$ManageDNS, # Allows ZeroTier to manage DNS [Alias('AllowGlobal')] [switch]$GlobalRoutes, # Allows ZeroTier managed routes to overlap public IP space [Alias('AllowDefault')] [switch]$DefaultRoute # Allows ZeroTier to override system default route (full tunnel) ) $DownloadURL = 'https://download.zerotier.com/dist/ZeroTier%20One.msi' $Installer = "$env:temp\ZeroTierOne.msi" $ZTCLI = 'C:\Program Files (x86)\ZeroTier\One\zerotier-cli.bat' # Set PowerShell to TLS 1.2 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 if ($Token) { # Check for required PowerShell version (7+) if (!($PSVersionTable.PSVersion.Major -ge 7)) { try { # Install PowerShell 7 if missing if (!(Test-Path "$env:SystemDrive\Program Files\PowerShell\7")) { Write-Output 'Installing PowerShell version 7...' Invoke-Expression "& { $(Invoke-RestMethod https://aka.ms/install-powershell.ps1) } -UseMSI -Quiet" } # Refresh PATH $env:Path = [System.Environment]::GetEnvironmentVariable('Path', 'Machine') + ';' + [System.Environment]::GetEnvironmentVariable('Path', 'User') # Restart script in PowerShell 7 pwsh -File "`"$PSCommandPath`"" @PSBoundParameters } catch { Write-Output 'PowerShell 7 was not installed. Update PowerShell and try again.' throw $Error } finally { exit $LASTEXITCODE } } } try { Write-Output 'Downloading ZeroTier...' Invoke-WebRequest -Uri $DownloadURL -OutFile $Installer Write-Output 'Installing ZeroTier...' if ($Headless) { # Install & unhide from installed programs list cmd /c msiexec /i $Installer /qn /norestart 'ZTHEADLESS=Yes' if ($env:PROCESSOR_ARCHITECTURE -eq 'AMD64') { $RegKey = 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{002609B2-C32C-481A-B17F-B7ED428427AC}' } else { $RegKey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{002609B2-C32C-481A-B17F-B7ED428427AC}' } Remove-ItemProperty -Path $RegKey -Name 'SystemComponent' -ErrorAction Ignore } else { # Install & close ui cmd /c msiexec /i $Installer /qn /norestart Stop-Process -Name 'zerotier_desktop_ui' -Force -ErrorAction Ignore } # Get Node ID $NodeID = (cmd /c $ZTCLI info).split(' ')[2] # API Member object properties $Member = @{ name = $env:COMPUTERNAME description = '' config = @{ authorized = $True } } | ConvertTo-Json # Prepare API request $Params = @{ Method = 'Post' Uri = "https://my.zerotier.com/api/network/$NetworkID/member/$NodeID" Body = $Member Authentication = 'Bearer' Token = ConvertTo-SecureString $Token -AsPlainText -Force MaximumRetryCount = 3 RetryIntervalSec = 5 } # Join network Write-Output "Configuring ZeroTier network $NetworkID as $NodeID..." if ($Token) { Invoke-RestMethod @Params } else { cmd /c $ZTCLI join $NetworkID } # Configure ZeroTier client if ($ManageDNS) { $AllowDNS = 1 } else { $AllowDNS = 0 } if ($GlobalRoutes) { $AllowGlobal = 1 } else { $AllowGlobal = 0 } if ($DefaultRoute) { $AllowDefault = 1 } else { $AllowDefault = 0 } cmd /c $ZTCLI set $NetworkID allowDNS=$AllowDNS allowGlobal=$AllowGlobal allowDefault=$AllowDefault | Out-Null } catch { throw $Error } finally { Remove-Item $Installer -Force -ErrorAction Ignore }