DscResources/VstsAgent/VstsAgent.psm1
function Set-TargetResource { [CmdletBinding()] param ( [ValidateSet("Present", "Absent")] [string]$Ensure = "Present", [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Name, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$ServerUrl, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$VstsPool, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$PoolId, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$VstsAccount, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$RunAsAccount, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Path, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Token, [ValidateSet("Running", "Stopped")] [string]$State = "Running", [string]$Version ) if ((Test-Path "$Path/.agent") -Or ($Ensure -eq "Absent")) { &"$Path/config" remove --unattended --auth pat --token $Token } if ($Ensure -eq "Present") { Write-Verbose "Downloading Agent..." DownloadAgent $Version $Path UnzipAgent "$Path\vsts-agent-$Version.zip" Write-Verbose "Installing Agent..." InstallAgent $Path $Name $ServerUrl $VstsPool $RunAsAccount $Token } if ($State -ne "Running") { Stop-Service "VSTS Agent ($VstsAccount.$Name)" } } function Get-TargetResource { [CmdletBinding()] param ( [ValidateSet("Present", "Absent")] [string]$Ensure = "Present", [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Name, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$ServerUrl, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$VstsPool, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$PoolId, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$VstsAccount, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$RunAsAccount, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Path, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Token, [ValidateSet("Running", "Stopped")] [string]$State = "Running", [string]$Version ) if (Test-Path "$Path/.agent") { $agentFile = ConvertFrom-Json -InputObject (Get-Content "$Path/.agent" -Raw) } $agent = Get-Wmiobject win32_service | Where-Object { $_.Name -eq "VSTS Agent ($VstsAccount.$Name)" } if ($agent -eq $null) { $agentStatus = "Stopped" } else { $agentStatus = $agent.State } return @{ Path = $Path RunAsAccount = $agent.StartName Version = (&"$Path/config" --version) PoolId = $agentFile.poolId ServerUrl = $agentFile.serverUrl Name = $agentFile.agentName } } function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [ValidateSet("Present", "Absent")] [string]$Ensure = "Present", [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Name, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$ServerUrl, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$VstsPool, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$PoolId, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$VstsAccount, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$RunAsAccount, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Path, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Token, [ValidateSet("Running", "Stopped")] [string]$State = "Running", [string]$Version ) $agent = Get-Wmiobject win32_service | Where-Object { $_.Name -eq "vstsagent.$VstsAccount.$Name" } if (($agent -ne $null) -And (Test-Path "$Path/.agent")) { $agentFile = ConvertFrom-Json -InputObject (Get-Content "$Path/.agent" -Raw) if ($agent.State -ne $State) { Write-Verbose "Agent $($agentFile.agentName) found but service is not $($State)." return $false } elseif ($agent.StartName -ne $RunAsAccount) { Write-Verbose "Agent $($agentFile.agentName) found but service account is not $($RunAsAccount)." return $false } elseif ($agentFile.poolId -ne $PoolId) { Write-Verbose "Agent $($agentFile.agentName) found but agent pool is not $($VstsPool)." return $false } elseif ($agentFile.agentName -ne $Name) { Write-Verbose "Agent exists but agent name is not $($Name)." return $false } elseif ($agentFile.serverUrl -ne $ServerUrl) { Write-Verbose "Agent $($agentFile.agentName) found but server url is not $($ServerUrl)." return $false } elseif ([String]::IsNullOrWhiteSpace($Version)) { Write-Verbose "Agent $($agentFile.agentName) found with matching settings." return $true } else { return ($Version -eq (&"$Path/config" --version)) } } Write-Verbose "Agent $($agentFile.agentName) not found." return $false } function DownloadAgent($Version, $Path) { if (!(Test-Path $Path)) { [void](New-Item $Path -ItemType "Directory") } $VstsAgentDownloadUrl = "https://vstsagentpackage.azureedge.net/agent/{0}/vsts-agent-win-x64-{0}.zip" add-type ` @" using System.Net; using System.Security.Cryptography.X509Certificates; public class TrustAllCertsPolicy : ICertificatePolicy { public bool CheckValidationResult( ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) { return true; } } "@ [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy $Null = Invoke-WebRequest -Uri [String]::Format($VstsAgentDownloadUrl, $Version), "$($Path)\vsts-agent-$($Version).zip" -OutFile "$($Path)\vsts-agent-$($Version).zip" } function UnzipAgent($Path) { Add-Type -AssemblyName System.IO.Compression.FileSystem Get-ChildItem -Path (Split-Path $Path -Parent) -Exclude (Split-Path $Path -Leaf) | Remove-Item -Recurse -Force [System.IO.Compression.ZipFile]::ExtractToDirectory($Path, (Split-Path $Path -Parent)) } function InstallAgent($Path, $Name, $ServerUrl, $AgentPool, $ServiceAccount, $Token) { &"$Path\config.cmd" --unattended --url $ServerUrl --auth pat --token $Token --pool $AgentPool --agent $Name --runAsService --windowsLogonAccount $ServiceAccount } |