VSTSAgent Cmdlets and DSC Resource
This commit is contained in:
Коммит
927b269e37
|
@ -0,0 +1 @@
|
|||
.vscode
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
|
@ -0,0 +1,95 @@
|
|||
# VSTS Agent Powershell Module
|
||||
|
||||
Tools for managing and automating your Visual Studio Team Services Agents.
|
||||
|
||||
## Builds
|
||||
|
||||
The `master` branch is manually built and deployed to the [PowerShell Gallery](https://www.powershellgallery.com/packages/VSTSAgent).
|
||||
|
||||
## Installation
|
||||
|
||||
```powershell
|
||||
Install-Module VSTSAgent -Scope CurrentUser
|
||||
```
|
||||
|
||||
## Using
|
||||
|
||||
### Cmdlets
|
||||
Get all of your installed VSTS Agents:
|
||||
|
||||
```powershell
|
||||
Get-VSTSAgent | Format-Table -AutoSize
|
||||
|
||||
# Sample Output
|
||||
# Name Version Account Status Uri
|
||||
# ---- ------- ------- ------ ---
|
||||
# Agent01 2.133.3 MyAccount Running file:///C:/Users/me/VSTSAgents/Agent01/
|
||||
# Agent02 2.133.3 MyAccount Running file:///C:/Users/me/VSTSAgents/Agent01/
|
||||
```
|
||||
|
||||
Install the latest VSTS Agent:
|
||||
|
||||
```powershell
|
||||
$pat = Read-Host -AsSecureString
|
||||
Install-VSTSAgent -Account 'MyAccount' -PAT $pat -Name 'Agent01'
|
||||
```
|
||||
|
||||
Uninstall any VSTS Agents:
|
||||
|
||||
```powershell
|
||||
Uninstall-VSTSAgent
|
||||
```
|
||||
|
||||
Find available VSTS Agents for installation:
|
||||
|
||||
```powershell
|
||||
Find-VSTSAgent
|
||||
```
|
||||
|
||||
Start and Stop installed Agents:
|
||||
```powershell
|
||||
Stop-VSTSAgent
|
||||
Start-VSTSAgent
|
||||
```
|
||||
|
||||
### DSC
|
||||
VSTSAgent includes the xVSTSAgent DSC Resource. An example configuration might look like:
|
||||
|
||||
```powershell
|
||||
Configuration Sample_xVSTSAgent_Install {
|
||||
param
|
||||
(
|
||||
[parameter(Mandatory = $true)]
|
||||
[PSCredential]$AccountCredential
|
||||
)
|
||||
Import-DscResource -ModuleName VSTSAgent
|
||||
|
||||
Node 'localhost' {
|
||||
|
||||
xVSTSAgent VSTSAgent {
|
||||
Name = 'Agent01'
|
||||
Account = 'MyAccount'
|
||||
AccountCredential = $AccountCredential
|
||||
AgentDirectory = 'C:\VSTSAgents'
|
||||
Ensure = 'Present'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
# Feedback
|
||||
To file issues or suggestions, please use the [Issues](https://github.com/Microsoft/unitysetup.powershell/issues) page for this project on GitHub.
|
||||
|
||||
|
||||
# Contributing
|
||||
|
||||
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.
|
||||
|
||||
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
||||
## Reporting Security Issues
|
||||
|
||||
Security issues and bugs should be reported privately, via email, to the Microsoft Security Response Center (MSRC) at [secure@microsoft.com](mailto:secure@microsoft.com). You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Further information, including the [MSRC PGP](https://technet.microsoft.com/en-us/security/dn606155) key, can be found in the [Security TechCenter](https://technet.microsoft.com/en-us/security/default).
|
|
@ -0,0 +1,216 @@
|
|||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
function Get-PrefixComputerName {
|
||||
param(
|
||||
[parameter(Mandatory = $true)]
|
||||
[string]$Name
|
||||
)
|
||||
|
||||
"$($env:COMPUTERNAME)-$Name"
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Returns the status of vsts agent installs.
|
||||
.PARAMETER Name
|
||||
The name of the agent to get.
|
||||
.PARAMETER AgentDirectory
|
||||
The directory to search for installed agents.
|
||||
.PARAMETER Account
|
||||
Unused - the account is discovered, not dictated.
|
||||
.PARAMETER AccountCredential
|
||||
Unused - not necessary for discovery.
|
||||
.PARAMETER LogonCredential
|
||||
Unused - not necessary for discovery.
|
||||
.PARAMETER Ensure
|
||||
Unused - not necessary for discovery.
|
||||
#>
|
||||
function Get-TargetResource {
|
||||
[CmdletBinding()]
|
||||
[OutputType([System.Collections.Hashtable])]
|
||||
param
|
||||
(
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.String]
|
||||
$Name,
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.String]
|
||||
$AgentDirectory,
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.String]
|
||||
$Account,
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.Management.Automation.PSCredential]
|
||||
$AccountCredential,
|
||||
|
||||
[System.Management.Automation.PSCredential]
|
||||
$LogonCredential,
|
||||
|
||||
[ValidateSet("Present", "Absent")]
|
||||
[System.String]
|
||||
$Ensure = 'Present',
|
||||
|
||||
[System.Boolean]
|
||||
$PrefixComputerName = $false
|
||||
)
|
||||
|
||||
if( $PrefixComputerName ) { $Name = Get-PrefixComputerName $Name }
|
||||
|
||||
$returnValue = @{ Name = $Name }
|
||||
$agent = Get-VSTSAgent -NameFilter $Name -AgentDirectory $AgentDirectory
|
||||
if ( $agent ) {
|
||||
$returnValue['Account'] = $agent.Account
|
||||
$returnValue['Ensure'] = 'Present'
|
||||
}
|
||||
else {
|
||||
$returnValue['Ensure'] = 'Absent'
|
||||
}
|
||||
|
||||
$returnValue
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Installs or uninstalls the specified agent.
|
||||
.PARAMETER Name
|
||||
What's the name of the agent we're concerned with?
|
||||
.PARAMETER Pool
|
||||
What's the pool of the agent we're concerned with? Note, only used on install.
|
||||
.PARAMETER AgentDirectory
|
||||
What directory is used for agents?
|
||||
.PARAMETER Account
|
||||
What VSTS account should we be concerned with?
|
||||
.PARAMETER AccountCredential
|
||||
The credential used to auth with VSTS.
|
||||
.PARAMETER LogonCredential
|
||||
What credential should the agent service use?
|
||||
.PARAMETER Ensure
|
||||
Should we ensure the agent exists or that it doesn't?
|
||||
#>
|
||||
function Set-TargetResource {
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.String]
|
||||
$Name,
|
||||
|
||||
[System.String]
|
||||
$Pool = 'Default',
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.String]
|
||||
$AgentDirectory,
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.String]
|
||||
$Account,
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.Management.Automation.PSCredential]
|
||||
$AccountCredential,
|
||||
|
||||
[System.Management.Automation.PSCredential]
|
||||
$LogonCredential,
|
||||
|
||||
[ValidateSet("Present", "Absent")]
|
||||
[System.String]
|
||||
$Ensure = 'Present',
|
||||
|
||||
[System.Boolean]
|
||||
$PrefixComputerName = $false
|
||||
)
|
||||
|
||||
if ( Test-TargetResource @PSBoundParameters ) { return }
|
||||
|
||||
if( $PrefixComputerName ) { $Name = Get-PrefixComputerName $Name }
|
||||
|
||||
if ( $Ensure -eq 'Present') {
|
||||
$installArgs = @{
|
||||
Name = $Name
|
||||
Pool = $Pool
|
||||
Account = $Account
|
||||
PAT = $AccountCredential.Password
|
||||
AgentDirectory = $AgentDirectory
|
||||
Replace = $true
|
||||
}
|
||||
|
||||
if ( $LogonCredential ) { $installArgs['LogonCredential'] = $LogonCredential }
|
||||
|
||||
Install-VSTSAgent @installArgs
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Test the status of the specified agent.
|
||||
.PARAMETER Name
|
||||
What's the name of the agent we're concerned with?
|
||||
.PARAMETER Pool
|
||||
Unused - Agent pool is not currently detectable.
|
||||
.PARAMETER AgentDirectory
|
||||
What directory should we search for agents?
|
||||
.PARAMETER Account
|
||||
What account should the agent use?
|
||||
.PARAMETER AccountCredential
|
||||
Unused - testing does not require credentials.
|
||||
.PARAMETER LogonCredential
|
||||
Unused - agent service logon user is not currently detectable.
|
||||
.PARAMETER Ensure
|
||||
Should the agent be present or absent?
|
||||
#>
|
||||
function Test-TargetResource {
|
||||
[CmdletBinding()]
|
||||
[OutputType([System.Boolean])]
|
||||
param
|
||||
(
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.String]
|
||||
$Name,
|
||||
|
||||
[System.String]
|
||||
$Pool = 'Default',
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.String]
|
||||
$AgentDirectory,
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.String]
|
||||
$Account,
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.Management.Automation.PSCredential]
|
||||
$AccountCredential,
|
||||
|
||||
[System.Management.Automation.PSCredential]
|
||||
$LogonCredential,
|
||||
|
||||
[ValidateSet("Present", "Absent")]
|
||||
[System.String]
|
||||
$Ensure = 'Present',
|
||||
|
||||
[System.Boolean]
|
||||
$PrefixComputerName = $false
|
||||
)
|
||||
|
||||
if( $PrefixComputerName ) { $Name = Get-PrefixComputerName $Name }
|
||||
|
||||
$agent = Get-VSTSAgent -NameFilter $Name -AgentDirectory $AgentDirectory
|
||||
switch ($Ensure) {
|
||||
'Present' {
|
||||
if ( -not $agent ) { return $false }
|
||||
if ( $agent.Account -ne $Account ) { return $false }
|
||||
return $true
|
||||
}
|
||||
'Absent' { return (-not $agent) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Export-ModuleMember -Function *-TargetResource
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
[ClassVersion("1.0.0.0"), FriendlyName("xVSTSAgent")]
|
||||
class xVSTSAgent : OMI_BaseResource
|
||||
{
|
||||
[Key] String Name;
|
||||
[Write] String Pool;
|
||||
[Required, EmbeddedInstance("MSFT_Credential")] String AccountCredential;
|
||||
[Required] String Account;
|
||||
[Write, EmbeddedInstance("MSFT_Credential")] String LogonCredential;
|
||||
[Required] String AgentDirectory;
|
||||
[Write] Boolean PrefixComputerName;
|
||||
[Write, ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure;
|
||||
};
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
<#
|
||||
Create a custom configuration by passing in necessary values
|
||||
#>
|
||||
Configuration Sample_xVSTSAgent {
|
||||
param
|
||||
(
|
||||
[parameter(Mandatory = $true)]
|
||||
[System.String]
|
||||
$Account,
|
||||
|
||||
[System.String]
|
||||
$Name = "$env:COMPUTERNAME",
|
||||
|
||||
[System.String]
|
||||
$Pool = 'Default',
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[pscredential]
|
||||
$AccountCredential,
|
||||
|
||||
[pscredential]
|
||||
$LogonCredential,
|
||||
|
||||
[System.String]
|
||||
$AgentDirectory = 'C:\VSTSAgents',
|
||||
|
||||
[ValidateSet('Present', 'Absent')]
|
||||
[System.String]
|
||||
$Ensure = 'Present',
|
||||
|
||||
[System.Boolean]
|
||||
$PrefixComputerName = $false
|
||||
)
|
||||
|
||||
Import-DscResource -ModuleName VSTSAgent
|
||||
|
||||
Node 'localhost' {
|
||||
|
||||
xVSTSAgent VSTSAgent {
|
||||
Name = $Name
|
||||
Pool = $Pool
|
||||
Account = $Account
|
||||
AccountCredential = $AccountCredential
|
||||
LogonCredential = $LogonCredential
|
||||
AgentDirectory = $AgentDirectory
|
||||
Ensure = $Ensure
|
||||
PrefixComputerName = $PrefixComputerName
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
#
|
||||
# Module manifest for module 'VSTSAgent'
|
||||
#
|
||||
# Generated by: jowitt
|
||||
#
|
||||
# Generated on: 2018-04-05
|
||||
#
|
||||
|
||||
@{
|
||||
|
||||
# Script module or binary module file associated with this manifest.
|
||||
RootModule = 'VSTSAgent.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.1'
|
||||
|
||||
# Supported PSEditions
|
||||
# CompatiblePSEditions = @()
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = '679b6302-ff19-4e53-a20f-eac2f531b5b6'
|
||||
|
||||
# Author of this module
|
||||
Author = 'Microsoft'
|
||||
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'Microsoft'
|
||||
|
||||
# Copyright statement for this module
|
||||
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.'
|
||||
|
||||
# Minimum version of the Windows PowerShell engine required by this module
|
||||
# PowerShellVersion = ''
|
||||
|
||||
# Name of the Windows PowerShell host required by this module
|
||||
# PowerShellHostName = ''
|
||||
|
||||
# Minimum version of the Windows PowerShell host required by this module
|
||||
# PowerShellHostVersion = ''
|
||||
|
||||
# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
|
||||
# DotNetFrameworkVersion = ''
|
||||
|
||||
# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
|
||||
# CLRVersion = ''
|
||||
|
||||
# Processor architecture (None, X86, Amd64) required by this module
|
||||
# ProcessorArchitecture = ''
|
||||
|
||||
# Modules that must be imported into the global environment prior to importing this module
|
||||
# RequiredModules = @()
|
||||
|
||||
# Assemblies that must be loaded prior to importing this module
|
||||
# RequiredAssemblies = @()
|
||||
|
||||
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
|
||||
# ScriptsToProcess = @()
|
||||
|
||||
# Type files (.ps1xml) to be loaded when importing this module
|
||||
# TypesToProcess = @()
|
||||
|
||||
# Format files (.ps1xml) to be loaded when importing this module
|
||||
# FormatsToProcess = @()
|
||||
|
||||
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
|
||||
# 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 = @(
|
||||
'Find-VSTSAgent',
|
||||
'Install-VSTSAgent',
|
||||
'Get-VSTSAgent',
|
||||
'Uninstall-VSTSAgent',
|
||||
'Start-VSTSAgent',
|
||||
'Stop-VSTSAgent'
|
||||
)
|
||||
|
||||
# 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 = @()
|
||||
|
||||
# Variables to export from this module
|
||||
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 = @()
|
||||
|
||||
# DSC resources to export from this module
|
||||
# DscResourcesToExport = @()
|
||||
|
||||
# List of all modules packaged with this module
|
||||
# ModuleList = @()
|
||||
|
||||
# List of all files packaged with this module
|
||||
# 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 = @{
|
||||
|
||||
PSData = @{
|
||||
|
||||
# Tags applied to this module. These help with module discovery in online galleries.
|
||||
Tags = @('VSTS')
|
||||
|
||||
# A URL to the license for this module.
|
||||
LicenseUri = 'https://github.com/Microsoft/VSTSAgent.PowerShell/blob/master/LICENSE'
|
||||
|
||||
# A URL to the main website for this project.
|
||||
ProjectUri = 'https://github.com/Microsoft/VSTSAgent.PowerShell'
|
||||
|
||||
# A URL to an icon representing this module.
|
||||
# IconUri = ''
|
||||
|
||||
# ReleaseNotes of this module
|
||||
# ReleaseNotes = ''
|
||||
|
||||
} # End of PSData hashtable
|
||||
|
||||
} # End of PrivateData hashtable
|
||||
|
||||
# HelpInfo URI of this module
|
||||
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 = ''
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,573 @@
|
|||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
class VSTSAgentVersion : System.IComparable {
|
||||
[int] $Major;
|
||||
[int] $Minor;
|
||||
[int] $Revision;
|
||||
|
||||
VSTSAgentVersion([string] $version) {
|
||||
|
||||
$version -match "(\d+)\.(\d+)\.(\d+)" | Out-Null
|
||||
if ( $Matches.Count -ne 4 ) { throw "Invalid VSTS Agent version: $version" }
|
||||
|
||||
$this.Major = [int]($Matches[1]);
|
||||
$this.Minor = [int]($Matches[2]);
|
||||
$this.Revision = [int]($Matches[3]);
|
||||
}
|
||||
|
||||
[string] ToString() {
|
||||
$result = "$($this.Major).$($this.Minor).$($this.Revision)"
|
||||
return $result
|
||||
}
|
||||
|
||||
[int] CompareTo([object]$obj) {
|
||||
if ($null -eq $obj) { return 1 }
|
||||
if ($obj -isnot [VSTSAgentVersion]) { throw "Object is not a VSTSAgentVersion"}
|
||||
|
||||
return [VSTSAgentVersion]::Compare($this, $obj)
|
||||
}
|
||||
|
||||
static [int] Compare([VSTSAgentVersion]$a, [VSTSAgentVersion]$b) {
|
||||
if ($a.Major -lt $b.Major) { return -1 }
|
||||
if ($a.Major -gt $b.Major) { return 1 }
|
||||
|
||||
if ($a.Minor -lt $b.Minor) { return -1 }
|
||||
if ($a.Minor -gt $b.Minor) { return 1 }
|
||||
|
||||
if ($a.Revision -lt $b.Revision) { return -1 }
|
||||
if ($a.Revision -gt $b.Revision) { return 1 }
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
[boolean] Equals ( [object]$obj ) {
|
||||
return [VSTSAgentVersion]::Compare($this, $obj) -eq 0;
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Enable TLS12 security protocol required by the GitHub https certs.
|
||||
#>
|
||||
function Set-SecurityProtocol {
|
||||
[CmdletBinding(SupportsShouldProcess)]
|
||||
param()
|
||||
$secProtocol = [System.Net.ServicePointManager]::SecurityProtocol
|
||||
if ( ($secProtocol -band [System.Net.SecurityProtocolType]::Tls12) -ne 0 ) { return }
|
||||
|
||||
if ( $PSCmdlet.ShouldProcess('[System.Net.ServicePointManager]::SecurityProtocol', 'Add [System.Net.SecurityProtocolType]::Tls12') ) {
|
||||
$secProtocol += [System.Net.SecurityProtocolType]::Tls12;
|
||||
[System.Net.ServicePointManager]::SecurityProtocol = $secProtocol
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Convert current OS platform to required Agent platform
|
||||
#>
|
||||
function Get-Platform {
|
||||
param ([string]$OS = $PSVersionTable.OS)
|
||||
|
||||
switch -regex ($OS) {
|
||||
'linux' { 'linux' }
|
||||
'darwin' { 'osx' }
|
||||
default { 'win' }
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Finds available VSTS agents
|
||||
.DESCRIPTION
|
||||
Searches the agent's Github release pages for available versions of the Agent.
|
||||
.PARAMETER MinimumVersion
|
||||
The minimum agent version required.
|
||||
.PARAMETER MaximumVersion
|
||||
The maximum agent version allowed.
|
||||
.PARAMETER RequiredVersion
|
||||
The required agent version.
|
||||
.PARAMETER Latest
|
||||
Find the latest available agent version.
|
||||
.PARAMETER Platform
|
||||
The platform required for the agent.
|
||||
#>
|
||||
function Find-VSTSAgent {
|
||||
[CmdletBinding( DefaultParameterSetName = "NoVersion")]
|
||||
param(
|
||||
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinVersion')]
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinMaxVersion')]
|
||||
[VSTSAgentVersion]$MinimumVersion,
|
||||
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MaxVersion')]
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinMaxVersion')]
|
||||
[VSTSAgentVersion]$MaximumVersion,
|
||||
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'RequiredVersion')]
|
||||
[VSTSAgentVersion]$RequiredVersion,
|
||||
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'Latest')]
|
||||
[switch]$Latest,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[string]$Platform
|
||||
)
|
||||
|
||||
if ( $Latest ) {
|
||||
|
||||
$findArgs = @{ }
|
||||
if ( $Platform ) { $findArgs['Platform'] = $Platform }
|
||||
$sortedAgents = Find-VSTSAgent @findArgs | Sort-Object -Descending -Property Version
|
||||
$sortedAgents | Where-Object { $_.Version -eq $sortedAgents[0].Version }
|
||||
return
|
||||
}
|
||||
|
||||
Set-SecurityProtocol
|
||||
|
||||
$rootUri = [uri]"https://github.com"
|
||||
$releasesRelativeUri = [uri]"/Microsoft/vsts-agent/releases"
|
||||
|
||||
$page = [uri]::new( $rootUri, $releasesRelativeUri )
|
||||
$queriedPages = @()
|
||||
|
||||
do {
|
||||
|
||||
$result = Invoke-WebRequest $page -UseBasicParsing
|
||||
$result.Links.href | Where-Object { $_ -match "vsts-agent-(\w+)-x64-(\d+\.\d+\.\d+)\..+$" } | ForEach-Object {
|
||||
|
||||
$instance = [PSCustomObject] @{
|
||||
'Platform' = $Matches[1]
|
||||
'Version' = [VSTSAgentVersion]$Matches[2]
|
||||
'Uri' = [uri]::new($_, [System.UriKind]::RelativeOrAbsolute)
|
||||
}
|
||||
|
||||
# Make it absolute
|
||||
if ( -not $instance.Uri.IsAbsoluteUri ) { $instance.Uri = [uri]::new($rootUri, $instance.Uri) }
|
||||
|
||||
if ( $RequiredVersion -and $instance.Version -ne $RequiredVersion) { return }
|
||||
if ( $MinimumVersion -and $instance.Version -lt $MinimumVersion) { return }
|
||||
if ( $MaximumVersion -and $instance.Version -gt $MaximumVersion) { return }
|
||||
if ( $Platform -and $instance.Platform -ne $Platform) { return }
|
||||
|
||||
Write-Verbose "Found agent at $($instance.Uri)"
|
||||
Write-Output $instance
|
||||
}
|
||||
|
||||
$queriedPages += $page
|
||||
$page = $result.Links.href | Where-Object {
|
||||
$_ -match "$releasesRelativeUri\?after=v(\d+\.\d+\.\d+)$" -and $queriedPages -notcontains $_
|
||||
} | Select-Object -First 1
|
||||
|
||||
} while ($page)
|
||||
}
|
||||
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Install a VSTS Agent.
|
||||
.DESCRIPTION
|
||||
Download and install a VSTS Agent matching the specified requirements.
|
||||
.PARAMETER MinimumVersion
|
||||
The minimum agent version required.
|
||||
.PARAMETER MaximumVersion
|
||||
The maximum agent version allowed.
|
||||
.PARAMETER RequiredVersion
|
||||
The required agent version.
|
||||
.PARAMETER AgentDirectory
|
||||
What directory should agents be installed into?
|
||||
.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 Replace
|
||||
Should the new agent replace any existing one on the account?
|
||||
.PARAMETER LogonCredential
|
||||
What user credentials should be used by the agent service?
|
||||
.PARAMETER Cache
|
||||
Where should agent downloads be cached?
|
||||
#>
|
||||
function Install-VSTSAgent {
|
||||
[CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = "NoVersion")]
|
||||
param(
|
||||
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinVersion')]
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinMaxVersion')]
|
||||
[VSTSAgentVersion]$MinimumVersion,
|
||||
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MaxVersion')]
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinMaxVersion')]
|
||||
[VSTSAgentVersion]$MaximumVersion,
|
||||
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'RequiredVersion')]
|
||||
[VSTSAgentVersion]$RequiredVersion,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[string]$AgentDirectory = [IO.Path]::Combine($env:USERPROFILE, "VSTSAgents"),
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[string]$Name = [System.Environment]::MachineName + "-$(Get-Random)",
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[string]$Pool = 'Default',
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[securestring]$PAT,
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[string]$Account,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[switch]$Replace,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[pscredential]$LogonCredential,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[string]$Cache = [io.Path]::Combine($env:USERPROFILE, ".vstsagents")
|
||||
)
|
||||
|
||||
if ($PSVersionTable.Platform -and $PSVersionTable.Platform -ne 'Win32NT') {
|
||||
throw "Not Implemented: Support for $($PSVersionTable.Platform), contributions welcome."
|
||||
}
|
||||
|
||||
if ( $Verbose ) { $VerbosePreference = 'Continue' }
|
||||
|
||||
$existing = Get-VSTSAgent -AgentDirectory $AgentDirectory -NameFilter $Name
|
||||
if ( $existing ) {
|
||||
if($Replace) {
|
||||
Uninstall-VSTSAgent -NameFilter $Name -AgentDirectory $AgentDirectory -PAT $PAT -ErrorAction Stop
|
||||
}
|
||||
else { throw "Agent $Name already exists in $AgentDirectory" }
|
||||
}
|
||||
|
||||
$findArgs = @{ 'Platform' = 'win' }
|
||||
if ( $MinimumVersion ) { $findArgs['MinimumVersion'] = $MinimumVersion }
|
||||
if ( $MaximumVersion ) { $findArgs['MaximumVersion'] = $MaximumVersion }
|
||||
if ( $RequiredVersion ) { $findArgs['RequiredVersion'] = $RequiredVersion }
|
||||
|
||||
$agent = Find-VSTSAgent @findArgs | Sort-Object -Descending -Property Version | Select-Object -First 1
|
||||
if ( -not $agent ) { throw "Could not find agent matching requirements." }
|
||||
|
||||
Write-Verbose "Installing agent at $($agent.Uri)"
|
||||
|
||||
$fileName = $agent.Uri.Segments[$agent.Uri.Segments.Length - 1]
|
||||
$destPath = [IO.Path]::Combine($Cache, "$($agent.Version)\$fileName")
|
||||
|
||||
if ( -not (Test-Path $destPath) ) {
|
||||
|
||||
$destDirectory = [io.path]::GetDirectoryName($destPath)
|
||||
if (!(Test-Path $destDirectory -PathType Container)) {
|
||||
New-Item "$destDirectory" -ItemType Directory | Out-Null
|
||||
}
|
||||
|
||||
Write-Verbose "Downloading agent from $($agent.Uri)"
|
||||
try { Start-BitsTransfer -Source $agent.Uri -Destination $destPath }
|
||||
catch { throw "Downloading $($agent.Uri) failed: $_" }
|
||||
}
|
||||
else { Write-Verbose "Skipping download as $destPath already exists." }
|
||||
|
||||
$agentFolder = [io.path]::Combine($AgentDirectory, $Name)
|
||||
Write-Verbose "Unzipping $destPath to $agentFolder"
|
||||
|
||||
if ( $PSVersionTable.PSVersion.Major -le 5 ) {
|
||||
Add-Type -AssemblyName System.IO.Compression.FileSystem -ErrorAction Stop
|
||||
}
|
||||
|
||||
[System.IO.Compression.ZipFile]::ExtractToDirectory($destPath, $agentFolder)
|
||||
|
||||
$configPath = [io.path]::combine($agentFolder, 'config.cmd')
|
||||
$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', `
|
||||
'pat', '--pool', "$Pool", '--agent', "$Name", '--runAsService')
|
||||
if ( $Replace ) { $configArgs += '--replace' }
|
||||
if ( $LogonCredential ) { $configArgs += '--windowsLogonAccount', $LogonCredential.UserName }
|
||||
|
||||
if ( -not $PSCmdlet.ShouldProcess("$configPath $configArgs", "Start-Process") ) { return }
|
||||
|
||||
$token = [System.Net.NetworkCredential]::new($null, $PAT).Password
|
||||
$configArgs += '--token', $token
|
||||
|
||||
if ( $LogonCredential ) {
|
||||
$configArgs += '--windowsLogonPassword', `
|
||||
[System.Net.NetworkCredential]::new($null, $LogonCredential.Password).Password
|
||||
}
|
||||
|
||||
$outFile = [io.path]::Combine($agentFolder, "out.log")
|
||||
$errorFile = [io.path]::Combine($agentFolder, "error.log")
|
||||
|
||||
Write-Verbose "Registering $Name to $Pool in $Account"
|
||||
Start-Process $configPath -ArgumentList $configArgs -NoNewWindow -Wait `
|
||||
-RedirectStandardOutput $outFile -RedirectStandardError $errorFile -ErrorAction Stop
|
||||
|
||||
if (Test-Path $errorFile) {
|
||||
Get-Content $errorFile | Write-Error
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Uninstall agents.
|
||||
.DESCRIPTION
|
||||
Uninstall any agents matching the specified criteria.
|
||||
.PARAMETER MinimumVersion
|
||||
Minimum version of agents to uninstall.
|
||||
.PARAMETER MaximumVersion
|
||||
Maximum version of agents to uninstall.
|
||||
.PARAMETER RequiredVersion
|
||||
Required version of agents to uninstall.
|
||||
.PARAMETER AgentDirectory
|
||||
What directory should be searched for existing agents?
|
||||
.PARAMETER NameFilter
|
||||
Only agents whose names match this filter will be uninstalled.
|
||||
.PARAMETER PAT
|
||||
The personal access token used to auth with VSTS.
|
||||
#>
|
||||
function Uninstall-VSTSAgent {
|
||||
[CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = "NoVersion")]
|
||||
param(
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinVersion')]
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinMaxVersion')]
|
||||
[VSTSAgentVersion]$MinimumVersion,
|
||||
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MaxVersion')]
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinMaxVersion')]
|
||||
[VSTSAgentVersion]$MaximumVersion,
|
||||
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'RequiredVersion')]
|
||||
[VSTSAgentVersion]$RequiredVersion,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[string]$AgentDirectory,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[string]$NameFilter,
|
||||
|
||||
[parameter(Mandatory = $true)]
|
||||
[securestring]$PAT
|
||||
)
|
||||
|
||||
$getArgs = @{}
|
||||
$PSBoundParameters.Keys | Where-Object { $_ -ne 'PAT' } | ForEach-Object {
|
||||
$getArgs[$_] = $PSBoundParameters[$_]
|
||||
}
|
||||
|
||||
$token = [System.Net.NetworkCredential]::new($null, $PAT).Password
|
||||
|
||||
Get-VSTSAgent @getArgs | ForEach-Object {
|
||||
if ( -not $PSCmdlet.ShouldProcess("$($_.Name) - $($_.Uri)", "Uninstall")) { return }
|
||||
|
||||
$configPath = [io.path]::Combine($_.Uri.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")
|
||||
|
||||
Start-Process $configPath -ArgumentList $configArgs -NoNewWindow -Wait `
|
||||
-RedirectStandardOutput $outFile -RedirectStandardError $errorFile
|
||||
|
||||
if ((Test-Path $errorFile) -and (Get-ChildItem $errorFile).Length -gt 0) {
|
||||
Get-Content $errorFile | Write-Error
|
||||
return; # Don't remove the agent folder if something went wrong.
|
||||
}
|
||||
|
||||
Remove-Item $_.Uri.LocalPath -Recurse -Force
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get all the agents installed.
|
||||
.PARAMETER MinimumVersion
|
||||
The minimum agent version to get.
|
||||
.PARAMETER MaximumVersion
|
||||
The maximum agent version to get.
|
||||
.PARAMETER RequiredVersion
|
||||
The required agent version to get.
|
||||
.PARAMETER AgentDirectory
|
||||
What directory should be searched for installed agents?
|
||||
.PARAMETER NameFilter
|
||||
Only agents whose names pass the filter are included.
|
||||
#>
|
||||
function Get-VSTSAgent {
|
||||
[CmdletBinding(DefaultParameterSetName = "NoVersion")]
|
||||
param(
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinVersion')]
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinMaxVersion')]
|
||||
[VSTSAgentVersion]$MinimumVersion,
|
||||
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MaxVersion')]
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinMaxVersion')]
|
||||
[VSTSAgentVersion]$MaximumVersion,
|
||||
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'RequiredVersion')]
|
||||
[VSTSAgentVersion]$RequiredVersion,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[string]$AgentDirectory = [io.Path]::Combine($env:USERPROFILE, "VSTSAgents"),
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[string]$NameFilter = '*'
|
||||
)
|
||||
|
||||
Get-ChildItem $AgentDirectory -Directory -Filter $NameFilter -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
|
||||
}
|
||||
|
||||
$version = & $configPath --version
|
||||
|
||||
if ( $RequiredVersion -and $version -ne $RequiredVersion) { return }
|
||||
if ( $MinimumVersion -and $version -lt $MinimumVersion) { return }
|
||||
if ( $MaximumVersion -and $version -gt $MaximumVersion) { return }
|
||||
|
||||
$name = $_.Name
|
||||
$service = Get-Service | ForEach-Object {
|
||||
if ( $_.Name -match "^vstsagent\.(.+)\.$name$" ) {
|
||||
[pscustomobject]@{ 'Account' = $Matches[1]; 'Status' = $_.Status }
|
||||
}
|
||||
}
|
||||
|
||||
[pscustomobject]@{
|
||||
'Name' = $name
|
||||
'Version' = $version
|
||||
'Account' = $service.Account
|
||||
'Status' = $service.Status
|
||||
'Uri' = [uri]::new( $configPath.Directory.FullName + [io.path]::DirectorySeparatorChar )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.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
|
||||
Starts any stopped services for matching VSTS Agents
|
||||
.PARAMETER MinimumVersion
|
||||
Mimumum version for agents.
|
||||
.PARAMETER MaximumVersion
|
||||
Maximum version for agents.
|
||||
.PARAMETER RequiredVersion
|
||||
Required version for agents.
|
||||
.PARAMETER AgentDirectory
|
||||
Directory to search installed agents.
|
||||
.PARAMETER NameFilter
|
||||
Only start services for agents whose names pass this filter.
|
||||
#>
|
||||
function Start-VSTSAgent {
|
||||
[CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = "NoVersion")]
|
||||
param(
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinVersion')]
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinMaxVersion')]
|
||||
[VSTSAgentVersion]$MinimumVersion,
|
||||
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MaxVersion')]
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinMaxVersion')]
|
||||
[VSTSAgentVersion]$MaximumVersion,
|
||||
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'RequiredVersion')]
|
||||
[VSTSAgentVersion]$RequiredVersion,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[string]$AgentDirectory,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[string]$NameFilter
|
||||
)
|
||||
|
||||
Get-VSTSAgent @PSBoundParameters | Get-VSTSAgentService -Status Stopped | ForEach-Object {
|
||||
if ( $PSCmdlet.ShouldProcess($_.Name, "Start-Service") ) {
|
||||
Start-Service $_
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Stop any running services for agents.
|
||||
.PARAMETER MinimumVersion
|
||||
Mimumum version for agents.
|
||||
.PARAMETER MaximumVersion
|
||||
Maximum version for agents.
|
||||
.PARAMETER RequiredVersion
|
||||
Required version for agents.
|
||||
.PARAMETER AgentDirectory
|
||||
Directory to search installed agents.
|
||||
.PARAMETER NameFilter
|
||||
Only start services for agents whose names pass this filter.
|
||||
#>
|
||||
function Stop-VSTSAgent {
|
||||
[CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = "NoVersion")]
|
||||
param(
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinVersion')]
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinMaxVersion')]
|
||||
[VSTSAgentVersion]$MinimumVersion,
|
||||
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MaxVersion')]
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'MinMaxVersion')]
|
||||
[VSTSAgentVersion]$MaximumVersion,
|
||||
|
||||
[parameter(Mandatory = $true, ParameterSetName = 'RequiredVersion')]
|
||||
[VSTSAgentVersion]$RequiredVersion,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[string]$AgentDirectory,
|
||||
|
||||
[parameter(Mandatory = $false)]
|
||||
[string]$NameFilter
|
||||
)
|
||||
|
||||
Get-VSTSAgent @PSBoundParameters | Get-VSTSAgentService -Status Running | ForEach-Object {
|
||||
if ( $PSCmdlet.ShouldProcess($_.Name, "Stop-Service") ) {
|
||||
Stop-Service $_
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
param([int]$Revision = 0, [string]$Suffix = '')
|
||||
Import-Module 'PowerShellGet' -MinimumVersion '1.6.0'
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$manifest = Test-ModuleManifest .\VSTSAgent\VSTSAgent.psd1
|
||||
$versionString = $manifest.Version.ToString()
|
||||
if ($manifest.PrivateData['PSData']['Prerelease']) {
|
||||
$versionString += "-$($manifest.PrivateData['PSData']['Prerelease'])"
|
||||
}
|
||||
Write-Host "Current Module Version: $versionString"
|
||||
|
||||
$newVersion = New-Object System.Version($manifest.Version.Major, $manifest.Version.Minor, $Revision)
|
||||
Update-ModuleManifest -ModuleVersion $newVersion -Prerelease $Suffix -Path .\VSTSAgent\VSTSAgent.psd1
|
||||
|
||||
$manifest = Test-ModuleManifest .\VSTSAgent\VSTSAgent.psd1
|
||||
$versionString = $manifest.Version.ToString()
|
||||
if ($manifest.PrivateData['PSData']['Prerelease']) {
|
||||
$versionString += "-$($manifest.PrivateData['PSData']['Prerelease'])"
|
||||
}
|
||||
Write-Host "New Module Version: $versionString"
|
Загрузка…
Ссылка в новой задаче