Support work folders, improve agent info scraping
This commit is contained in:
Родитель
7c2ea902b2
Коммит
a2c747bf62
|
@ -39,9 +39,13 @@ function Get-TargetResource {
|
|||
[System.String]
|
||||
$AgentDirectory,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[System.String]
|
||||
$Work,
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.String]
|
||||
$Account,
|
||||
$ServerUrl,
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.Management.Automation.PSCredential]
|
||||
|
@ -58,12 +62,14 @@ function Get-TargetResource {
|
|||
$PrefixComputerName = $false
|
||||
)
|
||||
|
||||
if( $PrefixComputerName ) { $Name = Get-PrefixComputerName $Name }
|
||||
if ( $PrefixComputerName ) { $Name = Get-PrefixComputerName $Name }
|
||||
|
||||
$returnValue = @{ Name = $Name }
|
||||
$returnValue = @{ 'Name' = $Name; 'AgentDirectory' = $AgentDirectory }
|
||||
$agent = Get-VSTSAgent -NameFilter $Name -AgentDirectory $AgentDirectory
|
||||
if ( $agent ) {
|
||||
$returnValue['Account'] = $agent.Account
|
||||
$returnValue['ServerUrl'] = $agent.ServerUrl
|
||||
$returnValue['Work'] = "$($agent.Work)"
|
||||
$returnValue['PoolId'] = "$($agent.PoolId)"
|
||||
$returnValue['Ensure'] = 'Present'
|
||||
}
|
||||
else {
|
||||
|
@ -106,9 +112,13 @@ function Set-TargetResource {
|
|||
[System.String]
|
||||
$AgentDirectory,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[System.String]
|
||||
$Work,
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.String]
|
||||
$Account,
|
||||
$ServerUrl,
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.Management.Automation.PSCredential]
|
||||
|
@ -127,22 +137,26 @@ function Set-TargetResource {
|
|||
|
||||
if ( Test-TargetResource @PSBoundParameters ) { return }
|
||||
|
||||
if( $PrefixComputerName ) { $Name = Get-PrefixComputerName $Name }
|
||||
if ( $PrefixComputerName ) { $Name = Get-PrefixComputerName $Name }
|
||||
|
||||
if ( $Ensure -eq 'Present') {
|
||||
$installArgs = @{
|
||||
Name = $Name
|
||||
Pool = $Pool
|
||||
Account = $Account
|
||||
PAT = $AccountCredential.Password
|
||||
AgentDirectory = $AgentDirectory
|
||||
Replace = $true
|
||||
'Name' = $Name
|
||||
'Pool' = $Pool
|
||||
'ServerUrl' = $ServerUrl
|
||||
'PAT' = $AccountCredential.Password
|
||||
'AgentDirectory' = $AgentDirectory
|
||||
'Replace' = $true
|
||||
}
|
||||
|
||||
if ( $Work ) { $installArgs['Work'] = $Work }
|
||||
if ( $LogonCredential ) { $installArgs['LogonCredential'] = $LogonCredential }
|
||||
|
||||
Install-VSTSAgent @installArgs
|
||||
}
|
||||
else {
|
||||
Uninstall-VSTSAgent -Name $Name -AgentDirectory $AgentDirectory -PAT $AccountCredential.Password
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
|
@ -179,9 +193,13 @@ function Test-TargetResource {
|
|||
[System.String]
|
||||
$AgentDirectory,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[System.String]
|
||||
$Work,
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.String]
|
||||
$Account,
|
||||
$ServerUrl,
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.Management.Automation.PSCredential]
|
||||
|
@ -198,16 +216,37 @@ function Test-TargetResource {
|
|||
$PrefixComputerName = $false
|
||||
)
|
||||
|
||||
if( $PrefixComputerName ) { $Name = Get-PrefixComputerName $Name }
|
||||
if ( $PrefixComputerName ) { $Name = Get-PrefixComputerName $Name }
|
||||
|
||||
$agent = Get-VSTSAgent -NameFilter $Name -AgentDirectory $AgentDirectory -Verbose
|
||||
|
||||
$agent = Get-VSTSAgent -NameFilter $Name -AgentDirectory $AgentDirectory
|
||||
switch ($Ensure) {
|
||||
'Present' {
|
||||
'Present' {
|
||||
if ( -not $agent ) { return $false }
|
||||
if ( $agent.Account -ne $Account ) { return $false }
|
||||
|
||||
Write-Verbose "Found agent pointed to $($agent.ServerUrl) and working from $($agent.Work)"
|
||||
if ( $agent.ServerUrl -ne $ServerUrl ) {
|
||||
Write-Verbose "ServerUrl mismatch: $($agent.ServerUrl) -ne $ServerUrl"
|
||||
return $false
|
||||
}
|
||||
if ( $Work -and $agent.Work -ne $Work ) {
|
||||
Write-Verbose "Work folder mismatch: $($agent.Work) -ne $Work"
|
||||
return $false
|
||||
}
|
||||
# TODO: Get back to pool name from $agent.PoolId.
|
||||
|
||||
Write-Verbose "VSTS Agent is Present"
|
||||
return $true
|
||||
}
|
||||
'Absent' {
|
||||
if ( $agent ) {
|
||||
Write-Verbose "Found agent pointed to $($agent.ServerUrl) and working from $($agent.Work)"
|
||||
return $false
|
||||
}
|
||||
|
||||
Write-Verbose "VSTS Agent is Absent"
|
||||
return $true
|
||||
}
|
||||
'Absent' { return (-not $agent) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,10 @@ class xVSTSAgent : OMI_BaseResource
|
|||
[Key] String Name;
|
||||
[Write] String Pool;
|
||||
[Required, EmbeddedInstance("MSFT_Credential")] String AccountCredential;
|
||||
[Required] String Account;
|
||||
[Required] String ServerUrl;
|
||||
[Write, EmbeddedInstance("MSFT_Credential")] String LogonCredential;
|
||||
[Required] String AgentDirectory;
|
||||
[Write] String Work;
|
||||
[Write] Boolean PrefixComputerName;
|
||||
[Write, ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure;
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@ Configuration Sample_xVSTSAgent {
|
|||
(
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.String]
|
||||
$Account,
|
||||
$ServerUrl,
|
||||
|
||||
[System.String]
|
||||
$Name = "$env:COMPUTERNAME",
|
||||
|
@ -26,6 +26,9 @@ Configuration Sample_xVSTSAgent {
|
|||
[System.String]
|
||||
$AgentDirectory = 'C:\VSTSAgents',
|
||||
|
||||
[System.String]
|
||||
$Work,
|
||||
|
||||
[ValidateSet('Present', 'Absent')]
|
||||
[System.String]
|
||||
$Ensure = 'Present',
|
||||
|
@ -34,17 +37,18 @@ Configuration Sample_xVSTSAgent {
|
|||
$PrefixComputerName = $false
|
||||
)
|
||||
|
||||
Import-DscResource -ModuleName VSTSAgent
|
||||
Import-DscResource -ModuleName VSTSAgent -ModuleVersion '2.0'
|
||||
|
||||
Node 'localhost' {
|
||||
|
||||
xVSTSAgent VSTSAgent {
|
||||
Name = $Name
|
||||
Pool = $Pool
|
||||
Account = $Account
|
||||
ServerUrl = $ServerUrl
|
||||
AccountCredential = $AccountCredential
|
||||
LogonCredential = $LogonCredential
|
||||
AgentDirectory = $AgentDirectory
|
||||
Work = $Work
|
||||
Ensure = $Ensure
|
||||
PrefixComputerName = $PrefixComputerName
|
||||
}
|
||||
|
|
|
@ -11,28 +11,28 @@
|
|||
@{
|
||||
|
||||
# Script module or binary module file associated with this manifest.
|
||||
RootModule = 'VSTSAgent.psm1'
|
||||
RootModule = 'VSTSAgent.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.1'
|
||||
ModuleVersion = '2.0'
|
||||
|
||||
# Supported PSEditions
|
||||
# CompatiblePSEditions = @()
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = '679b6302-ff19-4e53-a20f-eac2f531b5b6'
|
||||
GUID = '679b6302-ff19-4e53-a20f-eac2f531b5b6'
|
||||
|
||||
# Author of this module
|
||||
Author = 'Microsoft'
|
||||
Author = 'Microsoft'
|
||||
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'Microsoft'
|
||||
CompanyName = 'Microsoft'
|
||||
|
||||
# Copyright statement for this module
|
||||
Copyright = 'Copyright (c) Microsoft Corporation. All rights reserved.'
|
||||
Copyright = 'Copyright (c) Microsoft Corporation. All rights reserved.'
|
||||
|
||||
# Description of the functionality provided by this module
|
||||
Description = 'Tools for managing and automating your VSTS Agents.'
|
||||
Description = 'Tools for managing and automating your VSTS Agents.'
|
||||
|
||||
# Minimum version of the Windows PowerShell engine required by this module
|
||||
# PowerShellVersion = ''
|
||||
|
@ -71,7 +71,7 @@
|
|||
# NestedModules = @()
|
||||
|
||||
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
|
||||
FunctionsToExport = @(
|
||||
FunctionsToExport = @(
|
||||
'Find-VSTSAgent',
|
||||
'Install-VSTSAgent',
|
||||
'Get-VSTSAgent',
|
||||
|
@ -81,16 +81,16 @@
|
|||
)
|
||||
|
||||
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
|
||||
CmdletsToExport = @()
|
||||
CmdletsToExport = @()
|
||||
|
||||
# Variables to export from this module
|
||||
VariablesToExport = @()
|
||||
VariablesToExport = @()
|
||||
|
||||
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
|
||||
AliasesToExport = @()
|
||||
AliasesToExport = @()
|
||||
|
||||
# DSC resources to export from this module
|
||||
# DscResourcesToExport = @()
|
||||
DscResourcesToExport = @('xVSTSAgent')
|
||||
|
||||
# List of all modules packaged with this module
|
||||
# ModuleList = @()
|
||||
|
@ -99,7 +99,7 @@
|
|||
# FileList = @()
|
||||
|
||||
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
|
||||
PrivateData = @{
|
||||
PrivateData = @{
|
||||
|
||||
PSData = @{
|
||||
|
||||
|
@ -123,7 +123,7 @@
|
|||
} # End of PrivateData hashtable
|
||||
|
||||
# HelpInfo URI of this module
|
||||
HelpInfoURI = 'https://github.com/Microsoft/VSTSAgent.PowerShell/blob/master/README.md'
|
||||
HelpInfoURI = 'https://github.com/Microsoft/VSTSAgent.PowerShell/blob/master/README.md'
|
||||
|
||||
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
|
||||
# DefaultCommandPrefix = ''
|
||||
|
|
|
@ -176,14 +176,18 @@ function Find-VSTSAgent {
|
|||
The required agent version.
|
||||
.PARAMETER AgentDirectory
|
||||
What directory should agents be installed into?
|
||||
.PARAMETER Work
|
||||
Work directory where job data is stored. Defaults to _work under the
|
||||
root of the agent directory. The work directory is owned by a given
|
||||
agent and should not share between multiple agents.
|
||||
.PARAMETER Name
|
||||
What name should the agent use?
|
||||
.PARAMETER Pool
|
||||
What pool should the agent be registered into?
|
||||
.PARAMETER PAT
|
||||
What personal access token (PAT) should be used to auth with VSTS?
|
||||
.PARAMETER Account
|
||||
What account should the agent be registered to? As in "https://$Account.visualstudio.com".
|
||||
.PARAMETER ServerUrl
|
||||
What server url should the agent be registered to? Eg. 'https://account.visualstudio.com'
|
||||
.PARAMETER Replace
|
||||
Should the new agent replace any existing one on the account?
|
||||
.PARAMETER LogonCredential
|
||||
|
@ -209,6 +213,9 @@ function Install-VSTSAgent {
|
|||
[parameter(Mandatory = $false)]
|
||||
[string]$AgentDirectory = [IO.Path]::Combine($env:USERPROFILE, "VSTSAgents"),
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[string]$Work,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[string]$Name = [System.Environment]::MachineName + "-$(Get-Random)",
|
||||
|
||||
|
@ -219,7 +226,7 @@ function Install-VSTSAgent {
|
|||
[securestring]$PAT,
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[string]$Account,
|
||||
[uri]$ServerUrl,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[switch]$Replace,
|
||||
|
@ -239,7 +246,7 @@ function Install-VSTSAgent {
|
|||
|
||||
$existing = Get-VSTSAgent -AgentDirectory $AgentDirectory -NameFilter $Name
|
||||
if ( $existing ) {
|
||||
if($Replace) {
|
||||
if ($Replace) {
|
||||
Uninstall-VSTSAgent -NameFilter $Name -AgentDirectory $AgentDirectory -PAT $PAT -ErrorAction Stop
|
||||
}
|
||||
else { throw "Agent $Name already exists in $AgentDirectory" }
|
||||
|
@ -284,10 +291,11 @@ function Install-VSTSAgent {
|
|||
$configPath = Get-ChildItem $configPath -ErrorAction SilentlyContinue
|
||||
if ( -not $configPath ) { throw "Agent $agentFolder is missing config.cmd" }
|
||||
|
||||
[string[]]$configArgs = @('--unattended', '--url', "https://$Account.visualstudio.com", '--auth', `
|
||||
[string[]]$configArgs = @('--unattended', '--url', "$ServerUrl", '--auth', `
|
||||
'pat', '--pool', "$Pool", '--agent', "$Name", '--runAsService')
|
||||
if ( $Replace ) { $configArgs += '--replace' }
|
||||
if ( $LogonCredential ) { $configArgs += '--windowsLogonAccount', $LogonCredential.UserName }
|
||||
if ( $Work ) { $configArgs += '--work', $Work }
|
||||
|
||||
if ( -not $PSCmdlet.ShouldProcess("$configPath $configArgs", "Start-Process") ) { return }
|
||||
|
||||
|
@ -302,7 +310,7 @@ function Install-VSTSAgent {
|
|||
$outFile = [io.path]::Combine($agentFolder, "out.log")
|
||||
$errorFile = [io.path]::Combine($agentFolder, "error.log")
|
||||
|
||||
Write-Verbose "Registering $Name to $Pool in $Account"
|
||||
Write-Verbose "Registering $Name to $Pool at $ServerUrl"
|
||||
Start-Process $configPath -ArgumentList $configArgs -NoNewWindow -Wait `
|
||||
-RedirectStandardOutput $outFile -RedirectStandardError $errorFile -ErrorAction Stop
|
||||
|
||||
|
@ -361,13 +369,13 @@ function Uninstall-VSTSAgent {
|
|||
$token = [System.Net.NetworkCredential]::new($null, $PAT).Password
|
||||
|
||||
Get-VSTSAgent @getArgs | ForEach-Object {
|
||||
if ( -not $PSCmdlet.ShouldProcess("$($_.Name) - $($_.Uri)", "Uninstall")) { return }
|
||||
if ( -not $PSCmdlet.ShouldProcess("$($_.Name) - $($_.Path)", "Uninstall")) { return }
|
||||
|
||||
$configPath = [io.path]::Combine($_.Uri.LocalPath, 'config.cmd')
|
||||
$configPath = [io.path]::Combine($_.Path.LocalPath, 'config.cmd')
|
||||
$configArgs = @('remove', '--unattended', '--auth', 'pat', '--token', "$token")
|
||||
|
||||
$outFile = [io.path]::Combine($_.Uri.LocalPath, "out.log")
|
||||
$errorFile = [io.path]::Combine($_.Uri.LocalPath, "error.log")
|
||||
$outFile = [io.path]::Combine($_.Path.LocalPath, "out.log")
|
||||
$errorFile = [io.path]::Combine($_.Path.LocalPath, "error.log")
|
||||
|
||||
Start-Process $configPath -ArgumentList $configArgs -NoNewWindow -Wait `
|
||||
-RedirectStandardOutput $outFile -RedirectStandardError $errorFile
|
||||
|
@ -377,7 +385,10 @@ function Uninstall-VSTSAgent {
|
|||
return; # Don't remove the agent folder if something went wrong.
|
||||
}
|
||||
|
||||
Remove-Item $_.Uri.LocalPath -Recurse -Force
|
||||
Remove-Item $_.Path.LocalPath -Recurse -Force -ErrorAction Continue
|
||||
if ( $_.Work.IsAbsoluteUri ) {
|
||||
Remove-Item $_.Work.LocalPath -Recurse -Force -ErrorAction Continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,77 +427,63 @@ function Get-VSTSAgent {
|
|||
[string]$NameFilter = '*'
|
||||
)
|
||||
|
||||
Get-ChildItem $AgentDirectory -Directory -Filter $NameFilter -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
Get-ChildItem "$AgentDirectory\**\.agent" -Attributes '!D+H,!D' -ErrorAction SilentlyContinue |
|
||||
ForEach-Object {
|
||||
Write-Verbose "Found agent at $($_.FullName)"
|
||||
|
||||
$configPath = [io.path]::combine($_.FullName, 'config.cmd')
|
||||
$configPath = Get-ChildItem $configPath -ErrorAction SilentlyContinue
|
||||
if ( -not $configPath ) {
|
||||
Write-Warning "Agent $_ is missing config.cmd"
|
||||
return
|
||||
}
|
||||
$agentFullDirectory = $_.Directory.FullName
|
||||
$agentFullPath = $_.FullName
|
||||
|
||||
$version = & $configPath --version
|
||||
try {
|
||||
$agent = Get-Content $agentFullPath | ConvertFrom-Json
|
||||
Write-Verbose "Agent is named $($agent.agentName)"
|
||||
if ( $NameFilter -and ($agent.agentName -notlike $NameFilter) ) {
|
||||
Write-Verbose "Skipping agent because $($agent.agentName) is not like $NameFilter"
|
||||
return
|
||||
}
|
||||
|
||||
if ( $RequiredVersion -and $version -ne $RequiredVersion) { return }
|
||||
if ( $MinimumVersion -and $version -lt $MinimumVersion) { return }
|
||||
if ( $MaximumVersion -and $version -gt $MaximumVersion) { return }
|
||||
$configPath = [io.path]::combine($agentFullDirectory, 'config.cmd')
|
||||
$configPath = Get-ChildItem $configPath -ErrorAction SilentlyContinue
|
||||
if ( -not $configPath ) {
|
||||
Write-Warning "Agent $agentFullDirectory is missing config.cmd"
|
||||
return
|
||||
}
|
||||
|
||||
$name = $_.Name
|
||||
$service = Get-Service | ForEach-Object {
|
||||
if ( $_.Name -match "^vstsagent\.(.+)\.$name$" ) {
|
||||
[pscustomobject]@{ 'Account' = $Matches[1]; 'Status' = $_.Status }
|
||||
$version = & $configPath --version
|
||||
|
||||
if ( $RequiredVersion -and $version -ne $RequiredVersion) {
|
||||
Write-Verbose "Skipping agent because $version not match $RequiredVersion"
|
||||
return
|
||||
}
|
||||
if ( $MinimumVersion -and $version -lt $MinimumVersion) {
|
||||
Write-Verbose "Skipping agent because $version is less than $MinimumVersion"
|
||||
return
|
||||
}
|
||||
if ( $MaximumVersion -and $version -gt $MaximumVersion) {
|
||||
Write-Verbose "Skipping agent because $version is greater than $MaximumVersion"
|
||||
return
|
||||
}
|
||||
|
||||
if ( Test-Path "$($_.Directory.FullName)\.service" ) {
|
||||
$serviceName = Get-Content "$($_.Directory.FullName)\.service"
|
||||
$service = Get-Service $serviceName
|
||||
}
|
||||
|
||||
[pscustomobject]@{
|
||||
'Id' = $agent.agentId
|
||||
'Name' = $agent.agentName
|
||||
'PoolId' = $agent.poolId
|
||||
'ServerUrl' = [uri]$agent.serverUrl
|
||||
'Work' = [uri]$agent.workFolder
|
||||
'Service' = $service
|
||||
'Version' = $version
|
||||
'Path' = [uri]$agentFullDirectory
|
||||
}
|
||||
}
|
||||
|
||||
[pscustomobject]@{
|
||||
'Name' = $name
|
||||
'Version' = $version
|
||||
'Account' = $service.Account
|
||||
'Status' = $service.Status
|
||||
'Uri' = [uri]::new( $configPath.Directory.FullName + [io.path]::DirectorySeparatorChar )
|
||||
}
|
||||
catch { Write-Error "Exception processing agent at $agentFullPath\: $_" }
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get service for installed agent.
|
||||
.DESCRIPTION
|
||||
Get service for installed agent using VSTS agent naming scheme.
|
||||
.PARAMETER Name
|
||||
Name of the agent to find the service for.
|
||||
.PARAMETER Account
|
||||
Account of the agent to find the service for.
|
||||
.PARAMETER Status
|
||||
Filter services to only those whose status matches this.
|
||||
#>
|
||||
function Get-VSTSAgentService {
|
||||
param(
|
||||
[parameter(ValueFromPipelineByPropertyName, Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$Name,
|
||||
|
||||
[parameter(ValueFromPipelineByPropertyName, Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$Account,
|
||||
|
||||
[System.ServiceProcess.ServiceControllerStatus]$Status
|
||||
)
|
||||
|
||||
$serviceName = "vstsagent.$Account.$Name"
|
||||
$services = Get-Service -Name $serviceName -ErrorAction 'SilentlyContinue'
|
||||
|
||||
if ( $services.Count -eq 0 ) {
|
||||
Write-Error "Agent $($_.Name) has no matching service at $serviceName"
|
||||
}
|
||||
|
||||
if ( $Status ) {
|
||||
$services = $services | Where-Object { $_.Status -eq $Status }
|
||||
}
|
||||
|
||||
$services
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
@ -523,9 +520,13 @@ function Start-VSTSAgent {
|
|||
[string]$NameFilter
|
||||
)
|
||||
|
||||
Get-VSTSAgent @PSBoundParameters | Get-VSTSAgentService -Status Stopped | ForEach-Object {
|
||||
if ( $PSCmdlet.ShouldProcess($_.Name, "Start-Service") ) {
|
||||
Start-Service $_
|
||||
$stoppedAgents = Get-VSTSAgent @PSBoundParameters | Where-Object {
|
||||
$_.Service.Status -eq [System.ServiceProcess.ServiceControllerStatus]::Stopped
|
||||
}
|
||||
|
||||
$stoppedAgents | ForEach-Object {
|
||||
if ( $PSCmdlet.ShouldProcess($_.Service.Name, "Start-Service") ) {
|
||||
Start-Service $_.Service
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -565,9 +566,13 @@ function Stop-VSTSAgent {
|
|||
[string]$NameFilter
|
||||
)
|
||||
|
||||
Get-VSTSAgent @PSBoundParameters | Get-VSTSAgentService -Status Running | ForEach-Object {
|
||||
if ( $PSCmdlet.ShouldProcess($_.Name, "Stop-Service") ) {
|
||||
Stop-Service $_
|
||||
$runningAgents = Get-VSTSAgent @PSBoundParameters | Where-Object {
|
||||
$_.Service.Status -eq [System.ServiceProcess.ServiceControllerStatus]::Running
|
||||
}
|
||||
|
||||
$runningAgents | ForEach-Object {
|
||||
if ( $PSCmdlet.ShouldProcess($_.Service.Name, "Stop-Service") ) {
|
||||
Stop-Service $_.Service
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче