├── Images ├── Task.png ├── TaskOptionsAdvanced.png ├── TaskOptionsAgent.png ├── TaskOptionsDeploymentGroup.png ├── TaskOptionsInstallation.png └── icon.png ├── LICENSE.md ├── README.md ├── WindowsServiceManager ├── WindowsServiceManagerV1 │ ├── DeployWindowsService.ps1 │ ├── icon.png │ ├── ps_modules │ │ └── VstsTaskSdk │ │ │ ├── FindFunctions.ps1 │ │ │ ├── InputFunctions.ps1 │ │ │ ├── LegacyFindFunctions.ps1 │ │ │ ├── LocalizationFunctions.ps1 │ │ │ ├── LoggingCommandFunctions.ps1 │ │ │ ├── LongPathFunctions.ps1 │ │ │ ├── Minimatch.dll │ │ │ ├── OutFunctions.ps1 │ │ │ ├── PSGetModuleInfo.xml │ │ │ ├── ServerOMFunctions.ps1 │ │ │ ├── Strings │ │ │ └── resources.resjson │ │ │ │ ├── de-de │ │ │ │ └── resources.resjson │ │ │ │ ├── en-US │ │ │ │ └── resources.resjson │ │ │ │ ├── es-es │ │ │ │ └── resources.resjson │ │ │ │ ├── fr-fr │ │ │ │ └── resources.resjson │ │ │ │ ├── it-IT │ │ │ │ └── resources.resjson │ │ │ │ ├── ja-jp │ │ │ │ └── resources.resjson │ │ │ │ ├── ko-KR │ │ │ │ └── resources.resjson │ │ │ │ ├── ru-RU │ │ │ │ └── resources.resjson │ │ │ │ ├── zh-CN │ │ │ │ └── resources.resjson │ │ │ │ └── zh-TW │ │ │ │ └── resources.resjson │ │ │ ├── ToolFunctions.ps1 │ │ │ ├── TraceFunctions.ps1 │ │ │ ├── VstsTaskSdk.dll │ │ │ ├── VstsTaskSdk.psd1 │ │ │ ├── VstsTaskSdk.psm1 │ │ │ └── lib.json │ └── task.json ├── WindowsServiceManagerV2 │ ├── DeployWindowsService.ps1 │ ├── icon.png │ ├── ps_modules │ │ └── VstsTaskSdk │ │ │ ├── FindFunctions.ps1 │ │ │ ├── InputFunctions.ps1 │ │ │ ├── LegacyFindFunctions.ps1 │ │ │ ├── LocalizationFunctions.ps1 │ │ │ ├── LoggingCommandFunctions.ps1 │ │ │ ├── LongPathFunctions.ps1 │ │ │ ├── Minimatch.dll │ │ │ ├── OutFunctions.ps1 │ │ │ ├── PSGetModuleInfo.xml │ │ │ ├── ServerOMFunctions.ps1 │ │ │ ├── Strings │ │ │ └── resources.resjson │ │ │ │ ├── de-de │ │ │ │ └── resources.resjson │ │ │ │ ├── en-US │ │ │ │ └── resources.resjson │ │ │ │ ├── es-es │ │ │ │ └── resources.resjson │ │ │ │ ├── fr-fr │ │ │ │ └── resources.resjson │ │ │ │ ├── it-IT │ │ │ │ └── resources.resjson │ │ │ │ ├── ja-jp │ │ │ │ └── resources.resjson │ │ │ │ ├── ko-KR │ │ │ │ └── resources.resjson │ │ │ │ ├── ru-RU │ │ │ │ └── resources.resjson │ │ │ │ ├── zh-CN │ │ │ │ └── resources.resjson │ │ │ │ └── zh-TW │ │ │ │ └── resources.resjson │ │ │ ├── ToolFunctions.ps1 │ │ │ ├── TraceFunctions.ps1 │ │ │ ├── VstsTaskSdk.dll │ │ │ ├── VstsTaskSdk.psd1 │ │ │ ├── VstsTaskSdk.psm1 │ │ │ └── lib.json │ └── task.json ├── WindowsServiceManagerV3 │ ├── DeployWindowsService.ps1 │ ├── icon.png │ ├── ps_modules │ │ └── VstsTaskSdk │ │ │ ├── FindFunctions.ps1 │ │ │ ├── InputFunctions.ps1 │ │ │ ├── LegacyFindFunctions.ps1 │ │ │ ├── LocalizationFunctions.ps1 │ │ │ ├── LoggingCommandFunctions.ps1 │ │ │ ├── LongPathFunctions.ps1 │ │ │ ├── Minimatch.dll │ │ │ ├── OutFunctions.ps1 │ │ │ ├── PSGetModuleInfo.xml │ │ │ ├── ServerOMFunctions.ps1 │ │ │ ├── Strings │ │ │ └── resources.resjson │ │ │ │ ├── de-de │ │ │ │ └── resources.resjson │ │ │ │ ├── en-US │ │ │ │ └── resources.resjson │ │ │ │ ├── es-es │ │ │ │ └── resources.resjson │ │ │ │ ├── fr-fr │ │ │ │ └── resources.resjson │ │ │ │ ├── it-IT │ │ │ │ └── resources.resjson │ │ │ │ ├── ja-jp │ │ │ │ └── resources.resjson │ │ │ │ ├── ko-KR │ │ │ │ └── resources.resjson │ │ │ │ ├── ru-RU │ │ │ │ └── resources.resjson │ │ │ │ ├── zh-CN │ │ │ │ └── resources.resjson │ │ │ │ └── zh-TW │ │ │ │ └── resources.resjson │ │ │ ├── ToolFunctions.ps1 │ │ │ ├── TraceFunctions.ps1 │ │ │ ├── VstsTaskSdk.dll │ │ │ ├── VstsTaskSdk.psd1 │ │ │ ├── VstsTaskSdk.psm1 │ │ │ └── lib.json │ └── task.json └── WindowsServiceManagerV4 │ ├── Add-LocalUserToLogonAsAService.ps1 │ ├── DeployWindowsService.ps1 │ ├── icon.png │ ├── ps_modules │ └── VstsTaskSdk │ │ ├── FindFunctions.ps1 │ │ ├── InputFunctions.ps1 │ │ ├── LegacyFindFunctions.ps1 │ │ ├── LocalizationFunctions.ps1 │ │ ├── LoggingCommandFunctions.ps1 │ │ ├── LongPathFunctions.ps1 │ │ ├── Minimatch.dll │ │ ├── OutFunctions.ps1 │ │ ├── PSGetModuleInfo.xml │ │ ├── ServerOMFunctions.ps1 │ │ ├── Strings │ │ └── resources.resjson │ │ │ ├── de-de │ │ │ └── resources.resjson │ │ │ ├── en-US │ │ │ └── resources.resjson │ │ │ ├── es-es │ │ │ └── resources.resjson │ │ │ ├── fr-fr │ │ │ └── resources.resjson │ │ │ ├── it-IT │ │ │ └── resources.resjson │ │ │ ├── ja-jp │ │ │ └── resources.resjson │ │ │ ├── ko-KR │ │ │ └── resources.resjson │ │ │ ├── ru-RU │ │ │ └── resources.resjson │ │ │ ├── zh-CN │ │ │ └── resources.resjson │ │ │ └── zh-TW │ │ │ └── resources.resjson │ │ ├── ToolFunctions.ps1 │ │ ├── TraceFunctions.ps1 │ │ ├── VstsTaskSdk.dll │ │ ├── VstsTaskSdk.psd1 │ │ ├── VstsTaskSdk.psm1 │ │ └── lib.json │ └── task.json └── vss-extension.json /Images/Task.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/Images/Task.png -------------------------------------------------------------------------------- /Images/TaskOptionsAdvanced.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/Images/TaskOptionsAdvanced.png -------------------------------------------------------------------------------- /Images/TaskOptionsAgent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/Images/TaskOptionsAgent.png -------------------------------------------------------------------------------- /Images/TaskOptionsDeploymentGroup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/Images/TaskOptionsDeploymentGroup.png -------------------------------------------------------------------------------- /Images/TaskOptionsInstallation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/Images/TaskOptionsInstallation.png -------------------------------------------------------------------------------- /Images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/Images/icon.png -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2020] [Michael Dejulia] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WindowsServiceManager 2 | 3 | ## Tasks Included 4 | 5 | Windows Service Manager - Installs and deploys a windows service or [TopShelf](https://github.com/Topshelf/Topshelf) service on a target machine or a deployment group target. This task **does not** copy the binaries from an agent to a target machine. Use a deployment group, or use Microsoft's file copy task to copy the binaries from an agent to the target machine. 6 | 7 | 1. Locates the service by the **Service Name**. 8 | 2. Stops the service. 9 | 3. If **Stop process** is selected and the **Timeout** is reached, the process of the service will be stopped. 10 | 4. If **Clean binary install** is selected, removes all files in the parent directory of the .exe file. 11 | 5. If **Recreate service** is selected, deletes the service and recreates it. 12 | 6. Starts the service. 13 | 14 | ## Install and Run 15 | 16 | After installing the [Windows Service Manager](https://marketplace.visualstudio.com/items?itemName=MDSolutions.WindowsServiceManagerWindowsServiceManager) extension, open a release and add the 'Windows Service Manager' task. 17 | 18 | ![Task](https://github.com/Dejulia489/WindowsServiceManager/blob/master/Images/Task.png?raw=true "Task") 19 | 20 | [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=M69DLQ52C5RP2¤cy_code=USD&source=url) 21 | 22 | ## Task Options 23 | 24 | ### Task Options for Deployment Group 25 | 26 | ![Task Options](https://github.com/Dejulia489/WindowsServiceManager/blob/master/Images/TaskOptionsDeploymentGroup.png?raw=true "Task Options Deployment Group") 27 | 28 | 1. **Display name** - The name of the task. 29 | 2. **Deployment type** - Deploying with either an Agent or a Deployment Group Target. 30 | 3. **Service name** - The name of the Windows Service installed on the Deployment Group Target. 31 | 4. **Artifact path** - The path to the Artifact that contains the Windows Service binaries. 32 | 5. **Timeout** - The number of seconds to wait for the service to stop. 33 | 34 | ### Task Options for Agent 35 | 36 | ![Task Options](https://github.com/Dejulia489/WindowsServiceManager/blob/master/Images/TaskOptionsAgent.png?raw=true "Task Options Agent") 37 | 38 | 1. **Display name** - The name of the task. 39 | 2. **Machines** - Provide a comma separated list of machine IP addresses or FQDNs. Or provide output variable of other tasks. Eg: $(variableName). 40 | 3. **Admin login** - Administrator login for the target machines. 41 | 4. **Password** - Password for administrator login for the target machines. It can accept variable defined in Build/Release definitions as '$(passwordVariable)'. You may mark variable type as 'secret' to secure it. 42 | 5. **Service name** - The name of the Windows Service installed on the Deployment Group Target. 43 | 6. **Artifact path** - The path to the Artifact that contains the Windows Service binaries. 44 | 7. **Timeout** - The number of seconds to wait for the service to stop. 45 | 46 | ### Advanced Task Options 47 | 48 | ![Task Options](https://github.com/Dejulia489/WindowsServiceManager/blob/master/Images/TaskOptionsAdvanced.png?raw=true "Advanced Task Options") 49 | 50 | 1. **Stop process** - Stops the process if the service does not respond within the timeout. 51 | 2. **Clean binary install** - Removes all files inside the parent directory of the .exe file prior to copying the Artifact. 52 | 3. **Recreate service** - Deletes and recreates the service. 53 | 54 | ### Installation Task Options 55 | 56 | ![Task Options](https://github.com/Dejulia489/WindowsServiceManager/blob/master/Images/TaskOptionsInstallation.png?raw=true "Installation Task Options") 57 | 58 | 1. **Install the windows service** - Enables service installation. 59 | 2. **Start command** - Command to start the executable including arguments. Containing path is also used to Install Artifacts. 60 | 3. **Run As username** - The username the service should run as. 61 | 4. **Run As password** - The password for the Run As Username. It can accept variable defined in Build/Release definitions as '$(passwordVariable)'. You may mark variable type as 'secret' to secure it. 62 | 5. **Install as a TopShelf service** - Enables [TopShelf](https://github.com/Topshelf/Topshelf) installation. 63 | 6. **Instance name** - The name of the [TopShelf](https://github.com/Topshelf/Topshelf) instance. 64 | 7. **Install arguments** - The TopShelf installation arguments. 65 | 66 | ## Release Notes 67 | 68 | #### Version 4.4 69 | 70 | Implemented support to set Displayname, Description and StartupType for non TopShelf services. 71 | Implemented support for Command Arguments 72 | Implemented support to install dotnet based Service 73 | Implemented Recreate service flag 74 | Fixed Permission issue (add RunAsService Permission while installation) 75 | 76 | #### Version 4 77 | 78 | Implemented support for installing [TopShelf](https://github.com/Topshelf/Topshelf) windows services. 79 | 80 | #### Version 3 81 | 82 | Implemented feature request for installing a service and resolved bug for multiple machine support. 83 | 84 | #### Version 2 85 | 86 | Resolved bug for service name matching, service name will only support exact names. 87 | 88 | #### Version 1 89 | 90 | Supports deployment groups and agents using WinRM. 91 | 92 | #### Version 0 93 | 94 | Supports deployment groups only. 95 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/DeployWindowsService.ps1: -------------------------------------------------------------------------------- 1 | param 2 | ( 3 | [Parameter()] 4 | [string] 5 | $DeploymentType = (Get-VstsInput -Name 'DeploymentType' -Require), 6 | 7 | [Parameter()] 8 | [string] 9 | $ServiceName = (Get-VstsInput -Name 'ServiceName' -Require), 10 | 11 | [Parameter()] 12 | [string] 13 | $ArtifactPath = (Get-VstsInput -Name 'ArtifactPath' -Require), 14 | 15 | [Parameter()] 16 | [string] 17 | $TimeOut = (Get-VstsInput -Name 'TimeOut' -Require), 18 | 19 | [Parameter()] 20 | $CleanInstall = (Get-VstsInput -Name 'CleanInstall' -AsBool), 21 | 22 | [Parameter()] 23 | $StopProcess = (Get-VstsInput -Name 'StopProcess' -AsBool) 24 | ) 25 | Trace-VstsEnteringInvocation $MyInvocation 26 | 27 | If ($DeploymentType -eq 'Agent') 28 | { 29 | $machines = (Get-VstsInput -Name 'Machines' -Require) 30 | $adminLogin = Get-VstsInput -Name 'AdminLogin' -Require 31 | $password = Get-VstsInput -Name 'Password' -Require 32 | $securePassword = ConvertTo-SecureString $Password -AsPlainText -Force 33 | $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminLogin, $securePassword 34 | } 35 | $scriptBlock = { 36 | $serviceName = $args[0] 37 | $Timeout = $args[1] 38 | $StopProcess = $args[2] 39 | $CleanInstall = $args[3] 40 | $ArtifactPath = $args[4] 41 | Write-Output "Getting [$ServiceName]" 42 | $serviceObject = Get-WmiObject -Class Win32_Service | Where-Object {$PSItem.Name -match $ServiceName} 43 | If ($serviceObject) 44 | { 45 | If ($serviceObject.State -eq 'Running') 46 | { 47 | $stopServiceTimer = [Diagnostics.Stopwatch]::StartNew() 48 | Write-Output "Stopping [$ServiceName]" 49 | Do 50 | { 51 | $serviceObject = Get-WmiObject -Class Win32_Service | Where-Object {$PSItem.Name -match $ServiceName} 52 | $results = $serviceObject.StopService() 53 | If ($stopServiceTimer.Elapsed.TotalSeconds -gt $Timeout) 54 | { 55 | If ($StopProcess) 56 | { 57 | Write-Verbose "[$ServiceName] did not respond within [$Timeout] seconds, stopping process." 58 | $allProcesses = Get-Process 59 | $process = $allProcesses | Where-Object {$_.Path -like "$parentPath\*"} 60 | If ($process) 61 | { 62 | Write-Warning "Files are still in use by [$($process.ProcessName)], stopping the process!" 63 | $process | Stop-Process -Force -ErrorAction SilentlyContinue 64 | } 65 | } 66 | Else 67 | { 68 | Write-Error "[$ServiceName] did not respond within [$Timeout] seconds." -ErrorAction Stop 69 | } 70 | } 71 | $serviceObject = Get-WmiObject -Class Win32_Service | Where-Object {$PSItem.Name -match $ServiceName} 72 | } 73 | While ($serviceObject.State -ne 'Stopped') 74 | } 75 | $parentPath = ($serviceObject.PathName | Split-Path -Parent).Replace('"', '') 76 | Write-Output "Identified [$ServiceName] install location [$parentPath]" 77 | If (Test-Path $parentPath) 78 | { 79 | If ($CleanInstall) 80 | { 81 | Write-Output "Clean install set to [$CleanInstall], removing the contents of [$parentPath]" 82 | $cleanInstalltimer = [Diagnostics.Stopwatch]::StartNew() 83 | Do 84 | { 85 | Try 86 | { 87 | Get-ChildItem -Path $parentPath -Recurse -Force | Remove-Item -Recurse -Force -ErrorAction Stop 88 | } 89 | Catch 90 | { 91 | Switch -Wildcard ($PSItem.ErrorDetails.Message) 92 | { 93 | '*Cannot remove*' 94 | { 95 | If ($StopProcess) 96 | { 97 | Write-Verbose "[$ServiceName] did not respond within [$Timeout] seconds, stopping process." 98 | $allProcesses = Get-Process 99 | $process = $allProcesses | Where-Object {$_.Path -like "$parentPath\*"} 100 | If ($process) 101 | { 102 | Write-Warning "Files are still in use by [$($process.ProcessName)], stopping the process!" 103 | $process | Stop-Process -Force -ErrorAction SilentlyContinue 104 | } 105 | } 106 | else 107 | { 108 | Write-Error $PSItem -ErrorAction Stop 109 | } 110 | 111 | } 112 | Default 113 | { 114 | Write-Error $PSItem -ErrorAction Stop 115 | } 116 | } 117 | } 118 | If ($cleanInstalltimer.Elapsed.TotalSeconds -gt $Timeout) 119 | { 120 | Write-Error "[$ServiceName] did not respond within [$Timeout] seconds, clean install has failed." -ErrorAction Stop 121 | } 122 | } 123 | While (Get-ChildItem -Path $parentPath -Recurse -Force) 124 | $null = New-Item -ItemType Directory -Path $parentPath -Force 125 | } 126 | } 127 | Else 128 | { 129 | $null = New-Item -ItemType Directory -Path $parentPath -Force 130 | } 131 | Write-Output "Copying [$ArtifactPath] to [$parentPath]" 132 | Copy-Item -Path "$ArtifactPath\*" -Destination $parentPath -Force -Recurse -ErrorAction Stop 133 | Write-Output "Starting [$ServiceName]" 134 | $respone = $serviceObject.StartService() 135 | If ($respone.ReturnValue -ne 0) 136 | { 137 | Write-Error "Service responded with [$($respone.ReturnValue)]. See https://docs.microsoft.com/en-us/windows/desktop/cimwin32prov/startservice-method-in-class-win32-service for details." -ErrorAction Stop 138 | } 139 | } 140 | else 141 | { 142 | Write-Error "Unable to locate [$ServiceName] on [$Env:ComputerName], confirm the service is installed correctly." -ErrorAction Stop 143 | } 144 | } 145 | 146 | $invokeCommandSplat = @{ 147 | ScriptBlock = $scriptBlock 148 | } 149 | If($credential) 150 | { 151 | $invokeCommandSplat.Credential = $credential 152 | $invokeCommandSplat.ComputerName = $machines 153 | } 154 | Invoke-Command @invokeCommandSplat -ArgumentList $ServiceName, $TimeOut, $StopProcess, $CleanInstall, $ArtifactPath 155 | Trace-VstsLeavingInvocation $MyInvocation -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV1/icon.png -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/LocalizationFunctions.ps1: -------------------------------------------------------------------------------- 1 | $script:resourceStrings = @{ } 2 | 3 | <# 4 | .SYNOPSIS 5 | Gets a localized resource string. 6 | 7 | .DESCRIPTION 8 | Gets a localized resource string and optionally formats the string with arguments. 9 | 10 | If the format fails (due to a bad format string or incorrect expected arguments in the format string), then the format string is returned followed by each of the arguments (delimited by a space). 11 | 12 | If the lookup key is not found, then the lookup key is returned followed by each of the arguments (delimited by a space). 13 | 14 | .PARAMETER Require 15 | Writes an error to the error pipeline if the endpoint is not found. 16 | #> 17 | function Get-LocString { 18 | [CmdletBinding()] 19 | param( 20 | [Parameter(Mandatory = $true, Position = 1)] 21 | [string]$Key, 22 | [Parameter(Position = 2)] 23 | [object[]]$ArgumentList = @( )) 24 | 25 | # Due to the dynamically typed nature of PowerShell, a single null argument passed 26 | # to an array parameter is interpreted as a null array. 27 | if ([object]::ReferenceEquals($null, $ArgumentList)) { 28 | $ArgumentList = @( $null ) 29 | } 30 | 31 | # Lookup the format string. 32 | $format = '' 33 | if (!($format = $script:resourceStrings[$Key])) { 34 | # Warn the key was not found. Prevent recursion if the lookup key is the 35 | # "string resource key not found" lookup key. 36 | $resourceNotFoundKey = 'PSLIB_StringResourceKeyNotFound0' 37 | if ($key -ne $resourceNotFoundKey) { 38 | Write-Warning (Get-LocString -Key $resourceNotFoundKey -ArgumentList $Key) 39 | } 40 | 41 | # Fallback to just the key itself if there aren't any arguments to format. 42 | if (!$ArgumentList.Count) { return $key } 43 | 44 | # Otherwise fallback to the key followed by the arguments. 45 | $OFS = " " 46 | return "$key $ArgumentList" 47 | } 48 | 49 | # Return the string if there aren't any arguments to format. 50 | if (!$ArgumentList.Count) { return $format } 51 | 52 | try { 53 | [string]::Format($format, $ArgumentList) 54 | } catch { 55 | Write-Warning (Get-LocString -Key 'PSLIB_StringFormatFailed') 56 | $OFS = " " 57 | "$format $ArgumentList" 58 | } 59 | } 60 | 61 | <# 62 | .SYNOPSIS 63 | Imports resource strings for use with Get-VstsLocString. 64 | 65 | .DESCRIPTION 66 | Imports resource strings for use with Get-VstsLocString. The imported strings are stored in an internal resource string dictionary. Optionally, if a separate resource file for the current culture exists, then the localized strings from that file then imported (overlaid) into the same internal resource string dictionary. 67 | 68 | Resource strings from the SDK are prefixed with "PSLIB_". This prefix should be avoided for custom resource strings. 69 | 70 | .Parameter LiteralPath 71 | JSON file containing resource strings. 72 | 73 | .EXAMPLE 74 | Import-VstsLocStrings -LiteralPath $PSScriptRoot\Task.json 75 | 76 | Imports strings from messages section in the JSON file. If a messages section is not defined, then no strings are imported. Example messages section: 77 | { 78 | "messages": { 79 | "Hello": "Hello you!", 80 | "Hello0": "Hello {0}!" 81 | } 82 | } 83 | 84 | .EXAMPLE 85 | Import-VstsLocStrings -LiteralPath $PSScriptRoot\Task.json 86 | 87 | Overlays strings from an optional separate resource file for the current culture. 88 | 89 | Given the task variable System.Culture is set to 'de-DE'. This variable is set by the agent based on the current culture for the job. 90 | Given the file Task.json contains: 91 | { 92 | "messages": { 93 | "GoodDay": "Good day!", 94 | } 95 | } 96 | Given the file resources.resjson\de-DE\resources.resjson: 97 | { 98 | "loc.messages.GoodDay": "Guten Tag!" 99 | } 100 | 101 | The net result from the import command would be one new key-value pair added to the internal dictionary: Key = 'GoodDay', Value = 'Guten Tag!' 102 | #> 103 | function Import-LocStrings { 104 | [CmdletBinding()] 105 | param( 106 | [Parameter(Mandatory = $true)] 107 | [string]$LiteralPath) 108 | 109 | # Validate the file exists. 110 | if (!(Test-Path -LiteralPath $LiteralPath -PathType Leaf)) { 111 | Write-Warning (Get-LocString -Key PSLIB_FileNotFound0 -ArgumentList $LiteralPath) 112 | return 113 | } 114 | 115 | # Load the json. 116 | Write-Verbose "Loading resource strings from: $LiteralPath" 117 | $count = 0 118 | if ($messages = (Get-Content -LiteralPath $LiteralPath -Encoding UTF8 | Out-String | ConvertFrom-Json).messages) { 119 | # Add each resource string to the hashtable. 120 | foreach ($member in (Get-Member -InputObject $messages -MemberType NoteProperty)) { 121 | [string]$key = $member.Name 122 | $script:resourceStrings[$key] = $messages."$key" 123 | $count++ 124 | } 125 | } 126 | 127 | Write-Verbose "Loaded $count strings." 128 | 129 | # Get the culture. 130 | $culture = Get-TaskVariable -Name "System.Culture" -Default "en-US" 131 | 132 | # Load the resjson. 133 | $resjsonPath = "$([System.IO.Path]::GetDirectoryName($LiteralPath))\Strings\resources.resjson\$culture\resources.resjson" 134 | if (Test-Path -LiteralPath $resjsonPath) { 135 | Write-Verbose "Loading resource strings from: $resjsonPath" 136 | $count = 0 137 | $resjson = Get-Content -LiteralPath $resjsonPath -Encoding UTF8 | Out-String | ConvertFrom-Json 138 | foreach ($member in (Get-Member -Name loc.messages.* -InputObject $resjson -MemberType NoteProperty)) { 139 | if (!($value = $resjson."$($member.Name)")) { 140 | continue 141 | } 142 | 143 | [string]$key = $member.Name.Substring('loc.messages.'.Length) 144 | $script:resourceStrings[$key] = $value 145 | $count++ 146 | } 147 | 148 | Write-Verbose "Loaded $count strings." 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/Minimatch.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/Minimatch.dll -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/OutFunctions.ps1: -------------------------------------------------------------------------------- 1 | # TODO: It would be better if the Out-Default function resolved the underlying Out-Default 2 | # command in the begin block. This would allow for supporting other modules that override 3 | # Out-Default. 4 | $script:outDefaultCmdlet = $ExecutionContext.InvokeCommand.GetCmdlet("Microsoft.PowerShell.Core\Out-Default") 5 | 6 | ######################################## 7 | # Public functions. 8 | ######################################## 9 | function Out-Default { 10 | [CmdletBinding(ConfirmImpact = "Medium")] 11 | param( 12 | [Parameter(ValueFromPipeline = $true)] 13 | [System.Management.Automation.PSObject]$InputObject) 14 | 15 | begin { 16 | #Write-Host '[Entering Begin Out-Default]' 17 | $__sp = { & $script:outDefaultCmdlet @PSBoundParameters }.GetSteppablePipeline() 18 | $__sp.Begin($pscmdlet) 19 | #Write-Host '[Leaving Begin Out-Default]' 20 | } 21 | 22 | process { 23 | #Write-Host '[Entering Process Out-Default]' 24 | if ($_ -is [System.Management.Automation.ErrorRecord]) { 25 | Write-Verbose -Message 'Error record:' 4>&1 | Out-Default 26 | Write-Verbose -Message (Remove-TrailingNewLine (Out-String -InputObject $_ -Width 2147483647)) 4>&1 | Out-Default 27 | Write-Verbose -Message 'Script stack trace:' 4>&1 | Out-Default 28 | Write-Verbose -Message "$($_.ScriptStackTrace)" 4>&1 | Out-Default 29 | Write-Verbose -Message 'Exception:' 4>&1 | Out-Default 30 | Write-Verbose -Message $_.Exception.ToString() 4>&1 | Out-Default 31 | Write-TaskError -Message $_.Exception.Message 32 | } elseif ($_ -is [System.Management.Automation.WarningRecord]) { 33 | Write-TaskWarning -Message (Remove-TrailingNewLine (Out-String -InputObject $_ -Width 2147483647)) 34 | } elseif ($_ -is [System.Management.Automation.VerboseRecord] -and !$global:__vstsNoOverrideVerbose) { 35 | foreach ($private:str in (Format-DebugMessage -Object $_)) { 36 | Write-TaskVerbose -Message $private:str 37 | } 38 | } elseif ($_ -is [System.Management.Automation.DebugRecord] -and !$global:__vstsNoOverrideVerbose) { 39 | foreach ($private:str in (Format-DebugMessage -Object $_)) { 40 | Write-TaskDebug -Message $private:str 41 | } 42 | } else { 43 | # TODO: Consider using out-string here to control the width. As a security precaution it would actually be best to set it to max so wrapping doesn't interfere with secret masking. 44 | $__sp.Process($_) 45 | } 46 | 47 | #Write-Host '[Leaving Process Out-Default]' 48 | } 49 | 50 | end { 51 | #Write-Host '[Entering End Out-Default]' 52 | $__sp.End() 53 | #Write-Host '[Leaving End Out-Default]' 54 | } 55 | } 56 | 57 | ######################################## 58 | # Private functions. 59 | ######################################## 60 | function Format-DebugMessage { 61 | [CmdletBinding()] 62 | param([psobject]$Object) 63 | 64 | $private:str = Out-String -InputObject $Object -Width 2147483647 65 | $private:str = Remove-TrailingNewLine $private:str 66 | "$private:str".Replace("`r`n", "`n").Replace("`r", "`n").Split("`n"[0]) 67 | } 68 | 69 | function Remove-TrailingNewLine { 70 | [CmdletBinding()] 71 | param($Str) 72 | if ([object]::ReferenceEquals($Str, $null)) { 73 | return $Str 74 | } elseif ($Str.EndsWith("`r`n")) { 75 | return $Str.Substring(0, $Str.Length - 2) 76 | } else { 77 | return $Str 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/PSGetModuleInfo.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/PSGetModuleInfo.xml -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/Strings/resources.resjson/de-de/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "Agentversion {0} oder höher ist erforderlich.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Der Containerpfad wurde nicht gefunden: \"{0}\".", 4 | "loc.messages.PSLIB_EndpointAuth0": "\"{0}\"-Dienstendpunkt-Anmeldeinformationen", 5 | "loc.messages.PSLIB_EndpointUrl0": "\"{0}\"-Dienstendpunkt-URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Fehler beim Aufzählen von Unterverzeichnissen für den folgenden Pfad: \"{0}\"", 7 | "loc.messages.PSLIB_FileNotFound0": "Die Datei wurde nicht gefunden: \"{0}\".", 8 | "loc.messages.PSLIB_Input0": "\"{0}\"-Eingabe", 9 | "loc.messages.PSLIB_InvalidPattern0": "Ungültiges Muster: \"{0}\"", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Der Blattpfad wurde nicht gefunden: \"{0}\".", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "Fehler bei der Normalisierung bzw. Erweiterung des Pfads. Die Pfadlänge wurde vom Kernel32-Subsystem nicht zurückgegeben für: \"{0}\"", 12 | "loc.messages.PSLIB_PathNotFound0": "Der Pfad wurde nicht gefunden: \"{0}\".", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Der Prozess \"{0}\" wurde mit dem Code \"{1}\" beendet.", 14 | "loc.messages.PSLIB_Required0": "Erforderlich: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Fehler beim Zeichenfolgenformat.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "Der Zeichenfolgen-Ressourcenschlüssel wurde nicht gefunden: \"{0}\".", 17 | "loc.messages.PSLIB_TaskVariable0": "\"{0}\"-Taskvariable" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/Strings/resources.resjson/en-US/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "Agent version {0} or higher is required.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Container path not found: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "'{0}' service endpoint credentials", 5 | "loc.messages.PSLIB_EndpointUrl0": "'{0}' service endpoint URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Enumerating subdirectories failed for path: '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "File not found: '{0}'", 8 | "loc.messages.PSLIB_Input0": "'{0}' input", 9 | "loc.messages.PSLIB_InvalidPattern0": "Invalid pattern: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Leaf path not found: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "Path normalization/expansion failed. The path length was not returned by the Kernel32 subsystem for: '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "Path not found: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Process '{0}' exited with code '{1}'.", 14 | "loc.messages.PSLIB_Required0": "Required: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "String format failed.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "String resource key not found: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "'{0}' task variable" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/Strings/resources.resjson/es-es/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "Se require la versión {0} o posterior del agente.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "No se encuentra la ruta de acceso del contenedor: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "Credenciales del punto de conexión de servicio '{0}'", 5 | "loc.messages.PSLIB_EndpointUrl0": "URL del punto de conexión de servicio '{0}'", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "No se pudieron enumerar los subdirectorios de la ruta de acceso: '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "Archivo no encontrado: '{0}'", 8 | "loc.messages.PSLIB_Input0": "Entrada '{0}'", 9 | "loc.messages.PSLIB_InvalidPattern0": "Patrón no válido: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "No se encuentra la ruta de acceso de la hoja: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "No se pudo normalizar o expandir la ruta de acceso. El subsistema Kernel32 no devolvió la longitud de la ruta de acceso para: '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "No se encuentra la ruta de acceso: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "El proceso '{0}' finalizó con el código '{1}'.", 14 | "loc.messages.PSLIB_Required0": "Se requiere: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Error de formato de cadena.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "No se encuentra la clave de recurso de la cadena: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "Variable de tarea '{0}'" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/Strings/resources.resjson/fr-fr/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "L'agent version {0} (ou une version ultérieure) est obligatoire.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Le chemin du conteneur est introuvable : '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "Informations d'identification du point de terminaison de service '{0}'", 5 | "loc.messages.PSLIB_EndpointUrl0": "URL du point de terminaison de service '{0}'", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Échec de l'énumération des sous-répertoires pour le chemin : '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "Fichier introuvable : {0}.", 8 | "loc.messages.PSLIB_Input0": "Entrée '{0}'", 9 | "loc.messages.PSLIB_InvalidPattern0": "Modèle non valide : '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Le chemin feuille est introuvable : '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "Échec de la normalisation/l'expansion du chemin. La longueur du chemin n'a pas été retournée par le sous-système Kernel32 pour : '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "Chemin introuvable : '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Le processus '{0}' s'est arrêté avec le code '{1}'.", 14 | "loc.messages.PSLIB_Required0": "Obligatoire : {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Échec du format de la chaîne.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "Clé de la ressource de type chaîne introuvable : '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "Variable de tâche '{0}'" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/Strings/resources.resjson/it-IT/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "È richiesta la versione dell'agente {0} o superiore.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Percorso del contenitore non trovato: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "Credenziali dell'endpoint servizio '{0}'", 5 | "loc.messages.PSLIB_EndpointUrl0": "URL dell'endpoint servizio '{0}'", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "L'enumerazione delle sottodirectory per il percorso '{0}' non è riuscita", 7 | "loc.messages.PSLIB_FileNotFound0": "File non trovato: '{0}'", 8 | "loc.messages.PSLIB_Input0": "Input di '{0}'", 9 | "loc.messages.PSLIB_InvalidPattern0": "Criterio non valido: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Percorso foglia non trovato: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "La normalizzazione o l'espansione del percorso non è riuscita. Il sottosistema Kernel32 non ha restituito la lunghezza del percorso per '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "Percorso non trovato: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Il processo '{0}' è stato terminato ed è stato restituito il codice '{1}'.", 14 | "loc.messages.PSLIB_Required0": "Obbligatorio: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Errore nel formato della stringa.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "La chiave della risorsa stringa non è stata trovata: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "Variabile dell'attività '{0}'" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/Strings/resources.resjson/ja-jp/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "バージョン {0} 以降のエージェントが必要です。", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "コンテナーのパスが見つかりません: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "'{0}' サービス エンドポイントの資格情報", 5 | "loc.messages.PSLIB_EndpointUrl0": "'{0}' サービス エンドポイントの URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "パス '{0}' のサブディレクトリを列挙できませんでした", 7 | "loc.messages.PSLIB_FileNotFound0": "ファイルが見つかりません: '{0}'", 8 | "loc.messages.PSLIB_Input0": "'{0}' 入力", 9 | "loc.messages.PSLIB_InvalidPattern0": "使用できないパターンです: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "リーフ パスが見つかりません: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "パスの正規化/展開に失敗しました。Kernel32 サブシステムからパス '{0}' の長さが返されませんでした", 12 | "loc.messages.PSLIB_PathNotFound0": "パスが見つかりません: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "プロセス '{0}' がコード '{1}' で終了しました。", 14 | "loc.messages.PSLIB_Required0": "必要: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "文字列のフォーマットに失敗しました。", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "文字列のリソース キーが見つかりません: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "'{0}' タスク変数" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/Strings/resources.resjson/ko-KR/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "에이전트 버전 {0} 이상이 필요합니다.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "컨테이너 경로를 찾을 수 없음: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "'{0}' 서비스 끝점 자격 증명", 5 | "loc.messages.PSLIB_EndpointUrl0": "'{0}' 서비스 끝점 URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "경로에 대해 하위 디렉터리를 열거하지 못함: '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "{0} 파일을 찾을 수 없습니다.", 8 | "loc.messages.PSLIB_Input0": "'{0}' 입력", 9 | "loc.messages.PSLIB_InvalidPattern0": "잘못된 패턴: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Leaf 경로를 찾을 수 없음: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "경로 정규화/확장에 실패했습니다. 다음에 대해 Kernel32 subsystem에서 경로 길이를 반환하지 않음: '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "경로를 찾을 수 없음: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "'{1}' 코드로 '{0}' 프로세스가 종료되었습니다.", 14 | "loc.messages.PSLIB_Required0": "필수: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "문자열을 포맷하지 못했습니다.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "문자열 리소스 키를 찾을 수 없음: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "'{0}' 작업 변수" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/Strings/resources.resjson/ru-RU/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "Требуется версия агента {0} или более поздняя.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Путь к контейнеру не найден: \"{0}\".", 4 | "loc.messages.PSLIB_EndpointAuth0": "Учетные данные конечной точки службы \"{0}\"", 5 | "loc.messages.PSLIB_EndpointUrl0": "URL-адрес конечной точки службы \"{0}\"", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Сбой перечисления подкаталогов для пути: \"{0}\".", 7 | "loc.messages.PSLIB_FileNotFound0": "Файл не найден: \"{0}\".", 8 | "loc.messages.PSLIB_Input0": "Входные данные \"{0}\".", 9 | "loc.messages.PSLIB_InvalidPattern0": "Недопустимый шаблон: \"{0}\".", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Путь к конечному объекту не найден: \"{0}\".", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "Сбой нормализации и расширения пути. Длина пути не была возвращена подсистемой Kernel32 для: \"{0}\".", 12 | "loc.messages.PSLIB_PathNotFound0": "Путь не найден: \"{0}\".", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Процесс \"{0}\" завершил работу с кодом \"{1}\".", 14 | "loc.messages.PSLIB_Required0": "Требуется: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Сбой формата строки.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "Ключ ресурса строки не найден: \"{0}\".", 17 | "loc.messages.PSLIB_TaskVariable0": "Переменная задачи \"{0}\"" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/Strings/resources.resjson/zh-CN/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "需要代理版本 {0} 或更高版本。", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "找不到容器路径:“{0}”", 4 | "loc.messages.PSLIB_EndpointAuth0": "“{0}”服务终结点凭据", 5 | "loc.messages.PSLIB_EndpointUrl0": "“{0}”服务终结点 URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "枚举路径的子目录失败:“{0}”", 7 | "loc.messages.PSLIB_FileNotFound0": "找不到文件: {0}。", 8 | "loc.messages.PSLIB_Input0": "“{0}”输入", 9 | "loc.messages.PSLIB_InvalidPattern0": "无效的模式:“{0}”", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "找不到叶路径:“{0}”", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "路径规范化/扩展失败。路径长度不是由“{0}”的 Kernel32 子系统返回的", 12 | "loc.messages.PSLIB_PathNotFound0": "找不到路径:“{0}”", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "过程“{0}”已退出,代码为“{1}”。", 14 | "loc.messages.PSLIB_Required0": "必需: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "字符串格式无效。", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "找不到字符串资源关键字:“{0}”", 17 | "loc.messages.PSLIB_TaskVariable0": "“{0}”任务变量" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/Strings/resources.resjson/zh-TW/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "需要代理程式版本 {0} 或更新的版本。", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "找不到容器路徑: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "'{0}' 服務端點認證", 5 | "loc.messages.PSLIB_EndpointUrl0": "'{0}' 服務端點 URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "為路徑列舉子目錄失敗: '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "找不到檔案: '{0}'", 8 | "loc.messages.PSLIB_Input0": "'{0}' 輸入", 9 | "loc.messages.PSLIB_InvalidPattern0": "模式無效: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "找不到分葉路徑: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "路徑正規化/展開失敗。Kernel32 子系統未傳回 '{0}' 的路徑長度", 12 | "loc.messages.PSLIB_PathNotFound0": "找不到路徑: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "處理序 '{0}' 以返回碼 '{1}' 結束。", 14 | "loc.messages.PSLIB_Required0": "必要項: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "字串格式失敗。", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "找不到字串資源索引鍵: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "'{0}' 工作變數" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/ToolFunctions.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Asserts the agent version is at least the specified minimum. 4 | 5 | .PARAMETER Minimum 6 | Minimum version - must be 2.104.1 or higher. 7 | #> 8 | function Assert-Agent { 9 | [CmdletBinding()] 10 | param( 11 | [Parameter(Mandatory = $true)] 12 | [version]$Minimum) 13 | 14 | if (([version]'2.104.1').CompareTo($Minimum) -ge 1) { 15 | Write-Error "Assert-Agent requires the parameter to be 2.104.1 or higher." 16 | return 17 | } 18 | 19 | $agent = Get-TaskVariable -Name 'agent.version' 20 | if (!$agent -or $Minimum.CompareTo([version]$agent) -ge 1) { 21 | Write-Error (Get-LocString -Key 'PSLIB_AgentVersion0Required' -ArgumentList $Minimum) 22 | } 23 | } 24 | 25 | <# 26 | .SYNOPSIS 27 | Asserts that a path exists. Throws if the path does not exist. 28 | 29 | .PARAMETER PassThru 30 | True to return the path. 31 | #> 32 | function Assert-Path { 33 | [CmdletBinding()] 34 | param( 35 | [Parameter(Mandatory = $true)] 36 | [string]$LiteralPath, 37 | [Microsoft.PowerShell.Commands.TestPathType]$PathType = [Microsoft.PowerShell.Commands.TestPathType]::Any, 38 | [switch]$PassThru) 39 | 40 | if ($PathType -eq [Microsoft.PowerShell.Commands.TestPathType]::Any) { 41 | Write-Verbose "Asserting path exists: '$LiteralPath'" 42 | } else { 43 | Write-Verbose "Asserting $("$PathType".ToLowerInvariant()) path exists: '$LiteralPath'" 44 | } 45 | 46 | if (Test-Path -LiteralPath $LiteralPath -PathType $PathType) { 47 | if ($PassThru) { 48 | return $LiteralPath 49 | } 50 | 51 | return 52 | } 53 | 54 | $resourceKey = switch ($PathType) { 55 | ([Microsoft.PowerShell.Commands.TestPathType]::Container) { "PSLIB_ContainerPathNotFound0" ; break } 56 | ([Microsoft.PowerShell.Commands.TestPathType]::Leaf) { "PSLIB_LeafPathNotFound0" ; break } 57 | default { "PSLIB_PathNotFound0" } 58 | } 59 | 60 | throw (Get-LocString -Key $resourceKey -ArgumentList $LiteralPath) 61 | } 62 | 63 | <# 64 | .SYNOPSIS 65 | Executes an external program. 66 | 67 | .DESCRIPTION 68 | Executes an external program and waits for the process to exit. 69 | 70 | After calling this command, the exit code of the process can be retrieved from the variable $LASTEXITCODE. 71 | 72 | .PARAMETER Encoding 73 | This parameter not required for most scenarios. Indicates how to interpret the encoding from the external program. An example use case would be if an external program outputs UTF-16 XML and the output needs to be parsed. 74 | 75 | .PARAMETER RequireExitCodeZero 76 | Indicates whether to write an error to the error pipeline if the exit code is not zero. 77 | #> 78 | function Invoke-Tool { # TODO: RENAME TO INVOKE-PROCESS? 79 | [CmdletBinding()] 80 | param( 81 | [ValidatePattern('^[^\r\n]*$')] 82 | [Parameter(Mandatory = $true)] 83 | [string]$FileName, 84 | [ValidatePattern('^[^\r\n]*$')] 85 | [Parameter()] 86 | [string]$Arguments, 87 | [string]$WorkingDirectory, 88 | [System.Text.Encoding]$Encoding, 89 | [switch]$RequireExitCodeZero) 90 | 91 | Trace-EnteringInvocation $MyInvocation 92 | $isPushed = $false 93 | $originalEncoding = $null 94 | try { 95 | if ($Encoding) { 96 | $originalEncoding = [System.Console]::OutputEncoding 97 | [System.Console]::OutputEncoding = $Encoding 98 | } 99 | 100 | if ($WorkingDirectory) { 101 | Push-Location -LiteralPath $WorkingDirectory -ErrorAction Stop 102 | $isPushed = $true 103 | } 104 | 105 | $FileName = $FileName.Replace('"', '').Replace("'", "''") 106 | Write-Host "##[command]""$FileName"" $Arguments" 107 | Invoke-Expression "& '$FileName' --% $Arguments" 108 | Write-Verbose "Exit code: $LASTEXITCODE" 109 | if ($RequireExitCodeZero -and $LASTEXITCODE -ne 0) { 110 | Write-Error (Get-LocString -Key PSLIB_Process0ExitedWithCode1 -ArgumentList ([System.IO.Path]::GetFileName($FileName)), $LASTEXITCODE) 111 | } 112 | } finally { 113 | if ($originalEncoding) { 114 | [System.Console]::OutputEncoding = $originalEncoding 115 | } 116 | 117 | if ($isPushed) { 118 | Pop-Location 119 | } 120 | 121 | Trace-LeavingInvocation $MyInvocation 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/TraceFunctions.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Writes verbose information about the invocation being entered. 4 | 5 | .DESCRIPTION 6 | Used to trace verbose information when entering a function/script. Writes an entering message followed by a short description of the invocation. Additionally each bound parameter and unbound argument is also traced. 7 | 8 | .PARAMETER Parameter 9 | Wildcard pattern to control which bound parameters are traced. 10 | #> 11 | function Trace-EnteringInvocation { 12 | [CmdletBinding()] 13 | param( 14 | [Parameter(Mandatory = $true)] 15 | [System.Management.Automation.InvocationInfo]$InvocationInfo, 16 | [string[]]$Parameter = '*') 17 | 18 | Write-Verbose "Entering $(Get-InvocationDescription $InvocationInfo)." 19 | $OFS = ", " 20 | if ($InvocationInfo.BoundParameters.Count -and $Parameter.Count) { 21 | if ($Parameter.Count -eq 1 -and $Parameter[0] -eq '*') { 22 | # Trace all parameters. 23 | foreach ($key in $InvocationInfo.BoundParameters.Keys) { 24 | Write-Verbose " $($key): '$($InvocationInfo.BoundParameters[$key])'" 25 | } 26 | } else { 27 | # Trace matching parameters. 28 | foreach ($key in $InvocationInfo.BoundParameters.Keys) { 29 | foreach ($p in $Parameter) { 30 | if ($key -like $p) { 31 | Write-Verbose " $($key): '$($InvocationInfo.BoundParameters[$key])'" 32 | break 33 | } 34 | } 35 | } 36 | } 37 | } 38 | 39 | # Trace all unbound arguments. 40 | if (@($InvocationInfo.UnboundArguments).Count) { 41 | for ($i = 0 ; $i -lt $InvocationInfo.UnboundArguments.Count ; $i++) { 42 | Write-Verbose " args[$i]: '$($InvocationInfo.UnboundArguments[$i])'" 43 | } 44 | } 45 | } 46 | 47 | <# 48 | .SYNOPSIS 49 | Writes verbose information about the invocation being left. 50 | 51 | .DESCRIPTION 52 | Used to trace verbose information when leaving a function/script. Writes a leaving message followed by a short description of the invocation. 53 | #> 54 | function Trace-LeavingInvocation { 55 | [CmdletBinding()] 56 | param( 57 | [Parameter(Mandatory = $true)] 58 | [System.Management.Automation.InvocationInfo]$InvocationInfo) 59 | 60 | Write-Verbose "Leaving $(Get-InvocationDescription $InvocationInfo)." 61 | } 62 | 63 | <# 64 | .SYNOPSIS 65 | Writes verbose information about paths. 66 | 67 | .DESCRIPTION 68 | Writes verbose information about the paths. The paths are sorted and a the common root is written only once, followed by each relative path. 69 | 70 | .PARAMETER PassThru 71 | Indicates whether to return the sorted paths. 72 | #> 73 | function Trace-Path { 74 | [CmdletBinding()] 75 | param( 76 | [string[]]$Path, 77 | [switch]$PassThru) 78 | 79 | if ($Path.Count -eq 0) { 80 | Write-Verbose "No paths." 81 | if ($PassThru) { 82 | $Path 83 | } 84 | } elseif ($Path.Count -eq 1) { 85 | Write-Verbose "Path: $($Path[0])" 86 | if ($PassThru) { 87 | $Path 88 | } 89 | } else { 90 | # Find the greatest common root. 91 | $sorted = $Path | Sort-Object 92 | $firstPath = $sorted[0].ToCharArray() 93 | $lastPath = $sorted[-1].ToCharArray() 94 | $commonEndIndex = 0 95 | $j = if ($firstPath.Length -lt $lastPath.Length) { $firstPath.Length } else { $lastPath.Length } 96 | for ($i = 0 ; $i -lt $j ; $i++) { 97 | if ($firstPath[$i] -eq $lastPath[$i]) { 98 | if ($firstPath[$i] -eq '\') { 99 | $commonEndIndex = $i 100 | } 101 | } else { 102 | break 103 | } 104 | } 105 | 106 | if ($commonEndIndex -eq 0) { 107 | # No common root. 108 | Write-Verbose "Paths:" 109 | foreach ($p in $sorted) { 110 | Write-Verbose " $p" 111 | } 112 | } else { 113 | Write-Verbose "Paths: $($Path[0].Substring(0, $commonEndIndex + 1))" 114 | foreach ($p in $sorted) { 115 | Write-Verbose " $($p.Substring($commonEndIndex + 1))" 116 | } 117 | } 118 | 119 | if ($PassThru) { 120 | $sorted 121 | } 122 | } 123 | } 124 | 125 | ######################################## 126 | # Private functions. 127 | ######################################## 128 | function Get-InvocationDescription { 129 | [CmdletBinding()] 130 | param([System.Management.Automation.InvocationInfo]$InvocationInfo) 131 | 132 | if ($InvocationInfo.MyCommand.Path) { 133 | $InvocationInfo.MyCommand.Path 134 | } elseif ($InvocationInfo.MyCommand.Name) { 135 | $InvocationInfo.MyCommand.Name 136 | } else { 137 | $InvocationInfo.MyCommand.CommandType 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/VstsTaskSdk.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/VstsTaskSdk.dll -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/VstsTaskSdk.psd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/VstsTaskSdk.psd1 -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/VstsTaskSdk.psm1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | [ValidateNotNull()] 4 | [Parameter()] 5 | [hashtable]$ModuleParameters = @{ }) 6 | 7 | if ($host.Name -ne 'ConsoleHost') { 8 | Write-Warning "VstsTaskSdk is designed for use with powershell.exe (ConsoleHost). Output may be different when used with other hosts." 9 | } 10 | 11 | # Private module variables. 12 | [bool]$script:nonInteractive = "$($ModuleParameters['NonInteractive'])" -eq 'true' 13 | Write-Verbose "NonInteractive: $script:nonInteractive" 14 | 15 | # VstsTaskSdk.dll contains the TerminationException and NativeMethods for handle long path 16 | # We used to do inline C# in this powershell module 17 | # However when csc compile the inline C#, it will hit process env block size limit since it's not use unicode to encode env 18 | # To solve the env block size problem, we choose to put all inline C# into an assembly VstsTaskSdk.dll, signing it, package with the PS modules. 19 | Write-Verbose "Loading compiled helper $PSScriptRoot\VstsTaskSdk.dll." 20 | Add-Type -LiteralPath $PSScriptRoot\VstsTaskSdk.dll 21 | 22 | # Import/export functions. 23 | . "$PSScriptRoot\FindFunctions.ps1" 24 | . "$PSScriptRoot\InputFunctions.ps1" 25 | . "$PSScriptRoot\LegacyFindFunctions.ps1" 26 | . "$PSScriptRoot\LocalizationFunctions.ps1" 27 | . "$PSScriptRoot\LoggingCommandFunctions.ps1" 28 | . "$PSScriptRoot\LongPathFunctions.ps1" 29 | . "$PSScriptRoot\ServerOMFunctions.ps1" 30 | . "$PSScriptRoot\ToolFunctions.ps1" 31 | . "$PSScriptRoot\TraceFunctions.ps1" 32 | . "$PSScriptRoot\OutFunctions.ps1" # Load the out functions after all of the other functions are loaded. 33 | Export-ModuleMember -Function @( 34 | # Find functions. 35 | 'Find-Match' 36 | 'New-FindOptions' 37 | 'New-MatchOptions' 38 | 'Select-Match' 39 | # Input functions. 40 | 'Get-Endpoint' 41 | 'Get-SecureFileTicket' 42 | 'Get-SecureFileName' 43 | 'Get-Input' 44 | 'Get-TaskVariable' 45 | 'Get-TaskVariableInfo' 46 | 'Set-TaskVariable' 47 | # Legacy find functions. 48 | 'Find-Files' 49 | # Localization functions. 50 | 'Get-LocString' 51 | 'Import-LocStrings' 52 | # Logging command functions. 53 | 'Write-AddAttachment' 54 | 'Write-AddBuildTag' 55 | 'Write-AssociateArtifact' 56 | 'Write-LogDetail' 57 | 'Write-PrependPath' 58 | 'Write-SetEndpoint' 59 | 'Write-SetProgress' 60 | 'Write-SetResult' 61 | 'Write-SetSecret' 62 | 'Write-SetVariable' 63 | 'Write-TaskDebug' 64 | 'Write-TaskError' 65 | 'Write-TaskVerbose' 66 | 'Write-TaskWarning' 67 | 'Write-UpdateBuildNumber' 68 | 'Write-UpdateReleaseName' 69 | 'Write-UploadArtifact' 70 | 'Write-UploadBuildLog' 71 | 'Write-UploadFile' 72 | 'Write-UploadSummary' 73 | # Out functions. 74 | 'Out-Default' 75 | # Server OM functions. 76 | 'Get-AssemblyReference' 77 | 'Get-TfsClientCredentials' 78 | 'Get-TfsService' 79 | 'Get-VssCredentials' 80 | 'Get-VssHttpClient' 81 | # Tool functions. 82 | 'Assert-Agent' 83 | 'Assert-Path' 84 | 'Invoke-Tool' 85 | # Trace functions. 86 | 'Trace-EnteringInvocation' 87 | 'Trace-LeavingInvocation' 88 | 'Trace-Path' 89 | # Proxy functions 90 | 'Get-WebProxy' 91 | # Client cert functions 92 | 'Get-ClientCertificate' 93 | ) 94 | 95 | # Override Out-Default globally. 96 | $null = New-Item -Force -Path "function:\global:Out-Default" -Value (Get-Command -CommandType Function -Name Out-Default -ListImported) 97 | New-Alias -Name Out-Default -Value "global:Out-Default" -Scope global 98 | 99 | # Perform some initialization in a script block to enable merging the pipelines. 100 | $scriptText = @" 101 | # Load the SDK resource strings. 102 | Import-LocStrings "$PSScriptRoot\lib.json" 103 | 104 | # Load the module that contains ConvertTo-SecureString. 105 | if (!(Get-Module -Name Microsoft.PowerShell.Security)) { 106 | Write-Verbose "Importing the module 'Microsoft.PowerShell.Security'." 107 | Import-Module -Name Microsoft.PowerShell.Security 2>&1 | 108 | ForEach-Object { 109 | if (`$_ -is [System.Management.Automation.ErrorRecord]) { 110 | Write-Verbose `$_.Exception.Message 111 | } else { 112 | ,`$_ 113 | } 114 | } 115 | } 116 | "@ 117 | . ([scriptblock]::Create($scriptText)) 2>&1 3>&1 4>&1 5>&1 | Out-Default 118 | 119 | # Create Invoke-VstsTaskScript in a special way so it is not bound to the module. 120 | # Otherwise calling the task script block would run within the module context. 121 | # 122 | # An alternative way to solve the problem is to close the script block (i.e. closure). 123 | # However, that introduces a different problem. Closed script blocks are created within 124 | # a dynamic module. Each module gets it's own session state separate from the global 125 | # session state. When running in a regular script context, Import-Module calls import 126 | # the target module into the global session state. When running in a module context, 127 | # Import-Module calls import the target module into the caller module's session state. 128 | # 129 | # The goal of a task may include executing ad-hoc scripts. Therefore, task scripts 130 | # should run in regular script context. The end user specifying an ad-hoc script expects 131 | # the module import rules to be consistent with the default behavior (i.e. imported 132 | # into the global session state). 133 | $null = New-Item -Force -Path "function:\global:Invoke-VstsTaskScript" -Value ([scriptblock]::Create(@' 134 | [CmdletBinding()] 135 | param( 136 | [Parameter(Mandatory = $true)] 137 | [scriptblock]$ScriptBlock) 138 | 139 | try { 140 | $global:ErrorActionPreference = 'Stop' 141 | 142 | # Initialize the environment. 143 | $vstsModule = Get-Module -Name VstsTaskSdk 144 | Write-Verbose "$($vstsModule.Name) $($vstsModule.Version) commit $($vstsModule.PrivateData.PSData.CommitHash)" 4>&1 | Out-Default 145 | & $vstsModule Initialize-Inputs 4>&1 | Out-Default 146 | 147 | # Remove the local variable before calling the user's script. 148 | Remove-Variable -Name vstsModule 149 | 150 | # Call the user's script. 151 | $ScriptBlock | 152 | ForEach-Object { 153 | # Remove the scriptblock variable before calling it. 154 | Remove-Variable -Name ScriptBlock 155 | & $_ 2>&1 3>&1 4>&1 5>&1 | Out-Default 156 | } 157 | } catch [VstsTaskSdk.TerminationException] { 158 | # Special internal exception type to control the flow. Not currently intended 159 | # for public usage and subject to change. 160 | $global:__vstsNoOverrideVerbose = '' 161 | Write-Verbose "Task script terminated." 4>&1 | Out-Default 162 | } catch { 163 | $global:__vstsNoOverrideVerbose = '' 164 | Write-Verbose "Caught exception from task script." 4>&1 | Out-Default 165 | $_ | Out-Default 166 | Write-Host "##vso[task.complete result=Failed]" 167 | } 168 | '@)) 169 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/ps_modules/VstsTaskSdk/lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "messages": { 3 | "PSLIB_AgentVersion0Required": "Agent version {0} or higher is required.", 4 | "PSLIB_ContainerPathNotFound0": "Container path not found: '{0}'", 5 | "PSLIB_EndpointAuth0": "'{0}' service endpoint credentials", 6 | "PSLIB_EndpointUrl0": "'{0}' service endpoint URL", 7 | "PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Enumerating subdirectories failed for path: '{0}'", 8 | "PSLIB_FileNotFound0": "File not found: '{0}'", 9 | "PSLIB_Input0": "'{0}' input", 10 | "PSLIB_InvalidPattern0": "Invalid pattern: '{0}'", 11 | "PSLIB_LeafPathNotFound0": "Leaf path not found: '{0}'", 12 | "PSLIB_PathLengthNotReturnedFor0": "Path normalization/expansion failed. The path length was not returned by the Kernel32 subsystem for: '{0}'", 13 | "PSLIB_PathNotFound0": "Path not found: '{0}'", 14 | "PSLIB_Process0ExitedWithCode1": "Process '{0}' exited with code '{1}'.", 15 | "PSLIB_Required0": "Required: {0}", 16 | "PSLIB_StringFormatFailed": "String format failed.", 17 | "PSLIB_StringResourceKeyNotFound0": "String resource key not found: '{0}'", 18 | "PSLIB_TaskVariable0": "'{0}' task variable" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV1/task.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "7dad075d-a817-45ac-baab-4c1376d2885e", 3 | "name": "WindowsServiceManager", 4 | "friendlyName": "Windows Service Manager", 5 | "description": "Deploys a Windows Service with an Agent or a Deployment Group Target.", 6 | "helpMarkDown": "", 7 | "category": "Utility", 8 | "visibility": [ 9 | "Build", 10 | "Release" 11 | ], 12 | "author": "MDSolutions", 13 | "version": { 14 | "Major": 1, 15 | "Minor": 2, 16 | "Patch": 2 17 | }, 18 | "instanceNameFormat": "Deploy Windows Service", 19 | "groups": [ 20 | { 21 | "name": "advanced", 22 | "displayName": "Advanced", 23 | "isExpanded": true 24 | } 25 | ], 26 | "inputs": [ 27 | { 28 | "name": "DeploymentType", 29 | "type": "radio", 30 | "label": "Deployment Type", 31 | "required": true, 32 | "defaultValue": "Agent", 33 | "helpMarkDown": "Deploy with an Agent or a Deployment Group.", 34 | "options": { 35 | "Agent": "Agent", 36 | "DeploymentGroup": "Deployment Group" 37 | } 38 | }, 39 | { 40 | "name": "Machines", 41 | "label": "Machines", 42 | "required": true, 43 | "helpMarkDown": "Provide a comma separated list of machine IP addresses or FQDNs. Or provide output variable of other tasks. Eg: $(variableName).", 44 | "visibleRule": "DeploymentType=Agent" 45 | }, 46 | { 47 | "name": "AdminLogin", 48 | "label": "Admin Login", 49 | "required": true, 50 | "helpMarkDown": "Administrator login for the target machines.", 51 | "visibleRule": "DeploymentType=Agent" 52 | }, 53 | { 54 | "name": "Password", 55 | "label": "Password", 56 | "required": true, 57 | "helpMarkDown": "Password for administrator login for the target machines. It can accept variable defined in Build/Release definitions as '$(passwordVariable)'. You may mark variable type as 'secret' to secure it.", 58 | "visibleRule": "DeploymentType=Agent" 59 | }, 60 | { 61 | "name": "ServiceName", 62 | "type": "string", 63 | "label": "Service Name", 64 | "defaultValue": "", 65 | "required": true, 66 | "helpMarkDown": "The name of the windows service installed on the deployment group target." 67 | }, 68 | { 69 | "name": "ArtifactPath", 70 | "type": "filePath", 71 | "label": "Artifact Path", 72 | "defaultValue": "", 73 | "required": true, 74 | "helpMarkDown": "The path to the windows service artifact." 75 | }, 76 | { 77 | "name": "TimeOut", 78 | "type": "string", 79 | "label": "Timeout", 80 | "defaultValue": "30", 81 | "required": true, 82 | "helpMarkDown": "The number of seconds to wait for the service to stop." 83 | }, 84 | { 85 | "name": "StopProcess", 86 | "type": "boolean", 87 | "label": "Stop Process", 88 | "defaultValue": false, 89 | "groupName": "advanced", 90 | "helpMarkDown": "Stops the process if the service does not respond within the timeout limit." 91 | }, 92 | { 93 | "name": "CleanInstall", 94 | "type": "boolean", 95 | "label": "Clean Install", 96 | "defaultValue": false, 97 | "groupName": "advanced", 98 | "helpMarkDown": "Deletes all files from the Windows Service parent directory prior to deployment of the artifact." 99 | } 100 | ], 101 | "execution": { 102 | "PowerShell3": { 103 | "target": "DeployWindowsService.ps1", 104 | "workingDirectory": "$(currentDirectory)" 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/DeployWindowsService.ps1: -------------------------------------------------------------------------------- 1 | param 2 | ( 3 | [Parameter()] 4 | [string] 5 | $DeploymentType = (Get-VstsInput -Name 'DeploymentType' -Require), 6 | 7 | [Parameter()] 8 | [string] 9 | $ServiceName = (Get-VstsInput -Name 'ServiceName' -Require), 10 | 11 | [Parameter()] 12 | [string] 13 | $ArtifactPath = (Get-VstsInput -Name 'ArtifactPath' -Require), 14 | 15 | [Parameter()] 16 | [string] 17 | $TimeOut = (Get-VstsInput -Name 'TimeOut' -Require), 18 | 19 | [Parameter()] 20 | $CleanInstall = (Get-VstsInput -Name 'CleanInstall' -AsBool), 21 | 22 | [Parameter()] 23 | $StopProcess = (Get-VstsInput -Name 'StopProcess' -AsBool) 24 | ) 25 | Trace-VstsEnteringInvocation $MyInvocation 26 | 27 | If ($DeploymentType -eq 'Agent') 28 | { 29 | $machines = (Get-VstsInput -Name 'Machines' -Require) 30 | $adminLogin = Get-VstsInput -Name 'AdminLogin' -Require 31 | $password = Get-VstsInput -Name 'Password' -Require 32 | $securePassword = ConvertTo-SecureString $Password -AsPlainText -Force 33 | $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminLogin, $securePassword 34 | } 35 | $scriptBlock = { 36 | $serviceName = $args[0] 37 | $Timeout = $args[1] 38 | $StopProcess = $args[2] 39 | $CleanInstall = $args[3] 40 | $ArtifactPath = $args[4] 41 | Write-Output "Getting [$ServiceName]" 42 | $serviceObject = Get-WmiObject -Class Win32_Service | Where-Object {$PSItem.Name -eq $ServiceName} 43 | If ($serviceObject) 44 | { 45 | If ($serviceObject.State -eq 'Running') 46 | { 47 | $stopServiceTimer = [Diagnostics.Stopwatch]::StartNew() 48 | Write-Output "Stopping [$ServiceName]" 49 | Do 50 | { 51 | $serviceObject = Get-WmiObject -Class Win32_Service | Where-Object {$PSItem.Name -eq $ServiceName} 52 | $results = $serviceObject.StopService() 53 | If ($stopServiceTimer.Elapsed.TotalSeconds -gt $Timeout) 54 | { 55 | If ($StopProcess) 56 | { 57 | Write-Verbose "[$ServiceName] did not respond within [$Timeout] seconds, stopping process." 58 | $allProcesses = Get-Process 59 | $process = $allProcesses | Where-Object {$_.Path -like "$parentPath\*"} 60 | If ($process) 61 | { 62 | Write-Warning "Files are still in use by [$($process.ProcessName)], stopping the process!" 63 | $process | Stop-Process -Force -ErrorAction SilentlyContinue 64 | } 65 | } 66 | Else 67 | { 68 | Write-Error "[$ServiceName] did not respond within [$Timeout] seconds." -ErrorAction Stop 69 | } 70 | } 71 | $serviceObject = Get-WmiObject -Class Win32_Service | Where-Object {$PSItem.Name -eq $ServiceName} 72 | } 73 | While ($serviceObject.State -ne 'Stopped') 74 | } 75 | $parentPath = ($serviceObject.PathName | Split-Path -Parent).Replace('"', '') 76 | Write-Output "Identified [$ServiceName] install location [$parentPath]" 77 | If (Test-Path $parentPath) 78 | { 79 | If ($CleanInstall) 80 | { 81 | Write-Output "Clean install set to [$CleanInstall], removing the contents of [$parentPath]" 82 | $cleanInstalltimer = [Diagnostics.Stopwatch]::StartNew() 83 | Do 84 | { 85 | Try 86 | { 87 | Get-ChildItem -Path $parentPath -Recurse -Force | Remove-Item -Recurse -Force -ErrorAction Stop 88 | } 89 | Catch 90 | { 91 | Switch -Wildcard ($PSItem.ErrorDetails.Message) 92 | { 93 | '*Cannot remove*' 94 | { 95 | If ($StopProcess) 96 | { 97 | Write-Verbose "[$ServiceName] did not respond within [$Timeout] seconds, stopping process." 98 | $allProcesses = Get-Process 99 | $process = $allProcesses | Where-Object {$_.Path -like "$parentPath\*"} 100 | If ($process) 101 | { 102 | Write-Warning "Files are still in use by [$($process.ProcessName)], stopping the process!" 103 | $process | Stop-Process -Force -ErrorAction SilentlyContinue 104 | } 105 | } 106 | else 107 | { 108 | Write-Error $PSItem -ErrorAction Stop 109 | } 110 | 111 | } 112 | Default 113 | { 114 | Write-Error $PSItem -ErrorAction Stop 115 | } 116 | } 117 | } 118 | If ($cleanInstalltimer.Elapsed.TotalSeconds -gt $Timeout) 119 | { 120 | Write-Error "[$ServiceName] did not respond within [$Timeout] seconds, clean install has failed." -ErrorAction Stop 121 | } 122 | } 123 | While (Get-ChildItem -Path $parentPath -Recurse -Force) 124 | $null = New-Item -ItemType Directory -Path $parentPath -Force 125 | } 126 | } 127 | Else 128 | { 129 | $null = New-Item -ItemType Directory -Path $parentPath -Force 130 | } 131 | Write-Output "Copying [$ArtifactPath] to [$parentPath]" 132 | Copy-Item -Path "$ArtifactPath\*" -Destination $parentPath -Force -Recurse -ErrorAction Stop 133 | Write-Output "Starting [$ServiceName]" 134 | $respone = $serviceObject.StartService() 135 | If ($respone.ReturnValue -ne 0) 136 | { 137 | Write-Error "Service responded with [$($respone.ReturnValue)]. See https://docs.microsoft.com/en-us/windows/desktop/cimwin32prov/startservice-method-in-class-win32-service for details." -ErrorAction Stop 138 | } 139 | } 140 | else 141 | { 142 | Write-Error "Unable to locate [$ServiceName] on [$Env:ComputerName], confirm the service is installed correctly." -ErrorAction Stop 143 | } 144 | } 145 | 146 | $invokeCommandSplat = @{ 147 | ScriptBlock = $scriptBlock 148 | } 149 | If($credential) 150 | { 151 | $invokeCommandSplat.Credential = $credential 152 | $invokeCommandSplat.ComputerName = $machines 153 | } 154 | Invoke-Command @invokeCommandSplat -ArgumentList $ServiceName, $TimeOut, $StopProcess, $CleanInstall, $ArtifactPath 155 | Trace-VstsLeavingInvocation $MyInvocation -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV2/icon.png -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/LocalizationFunctions.ps1: -------------------------------------------------------------------------------- 1 | $script:resourceStrings = @{ } 2 | 3 | <# 4 | .SYNOPSIS 5 | Gets a localized resource string. 6 | 7 | .DESCRIPTION 8 | Gets a localized resource string and optionally formats the string with arguments. 9 | 10 | If the format fails (due to a bad format string or incorrect expected arguments in the format string), then the format string is returned followed by each of the arguments (delimited by a space). 11 | 12 | If the lookup key is not found, then the lookup key is returned followed by each of the arguments (delimited by a space). 13 | 14 | .PARAMETER Require 15 | Writes an error to the error pipeline if the endpoint is not found. 16 | #> 17 | function Get-LocString { 18 | [CmdletBinding()] 19 | param( 20 | [Parameter(Mandatory = $true, Position = 1)] 21 | [string]$Key, 22 | [Parameter(Position = 2)] 23 | [object[]]$ArgumentList = @( )) 24 | 25 | # Due to the dynamically typed nature of PowerShell, a single null argument passed 26 | # to an array parameter is interpreted as a null array. 27 | if ([object]::ReferenceEquals($null, $ArgumentList)) { 28 | $ArgumentList = @( $null ) 29 | } 30 | 31 | # Lookup the format string. 32 | $format = '' 33 | if (!($format = $script:resourceStrings[$Key])) { 34 | # Warn the key was not found. Prevent recursion if the lookup key is the 35 | # "string resource key not found" lookup key. 36 | $resourceNotFoundKey = 'PSLIB_StringResourceKeyNotFound0' 37 | if ($key -ne $resourceNotFoundKey) { 38 | Write-Warning (Get-LocString -Key $resourceNotFoundKey -ArgumentList $Key) 39 | } 40 | 41 | # Fallback to just the key itself if there aren't any arguments to format. 42 | if (!$ArgumentList.Count) { return $key } 43 | 44 | # Otherwise fallback to the key followed by the arguments. 45 | $OFS = " " 46 | return "$key $ArgumentList" 47 | } 48 | 49 | # Return the string if there aren't any arguments to format. 50 | if (!$ArgumentList.Count) { return $format } 51 | 52 | try { 53 | [string]::Format($format, $ArgumentList) 54 | } catch { 55 | Write-Warning (Get-LocString -Key 'PSLIB_StringFormatFailed') 56 | $OFS = " " 57 | "$format $ArgumentList" 58 | } 59 | } 60 | 61 | <# 62 | .SYNOPSIS 63 | Imports resource strings for use with Get-VstsLocString. 64 | 65 | .DESCRIPTION 66 | Imports resource strings for use with Get-VstsLocString. The imported strings are stored in an internal resource string dictionary. Optionally, if a separate resource file for the current culture exists, then the localized strings from that file then imported (overlaid) into the same internal resource string dictionary. 67 | 68 | Resource strings from the SDK are prefixed with "PSLIB_". This prefix should be avoided for custom resource strings. 69 | 70 | .Parameter LiteralPath 71 | JSON file containing resource strings. 72 | 73 | .EXAMPLE 74 | Import-VstsLocStrings -LiteralPath $PSScriptRoot\Task.json 75 | 76 | Imports strings from messages section in the JSON file. If a messages section is not defined, then no strings are imported. Example messages section: 77 | { 78 | "messages": { 79 | "Hello": "Hello you!", 80 | "Hello0": "Hello {0}!" 81 | } 82 | } 83 | 84 | .EXAMPLE 85 | Import-VstsLocStrings -LiteralPath $PSScriptRoot\Task.json 86 | 87 | Overlays strings from an optional separate resource file for the current culture. 88 | 89 | Given the task variable System.Culture is set to 'de-DE'. This variable is set by the agent based on the current culture for the job. 90 | Given the file Task.json contains: 91 | { 92 | "messages": { 93 | "GoodDay": "Good day!", 94 | } 95 | } 96 | Given the file resources.resjson\de-DE\resources.resjson: 97 | { 98 | "loc.messages.GoodDay": "Guten Tag!" 99 | } 100 | 101 | The net result from the import command would be one new key-value pair added to the internal dictionary: Key = 'GoodDay', Value = 'Guten Tag!' 102 | #> 103 | function Import-LocStrings { 104 | [CmdletBinding()] 105 | param( 106 | [Parameter(Mandatory = $true)] 107 | [string]$LiteralPath) 108 | 109 | # Validate the file exists. 110 | if (!(Test-Path -LiteralPath $LiteralPath -PathType Leaf)) { 111 | Write-Warning (Get-LocString -Key PSLIB_FileNotFound0 -ArgumentList $LiteralPath) 112 | return 113 | } 114 | 115 | # Load the json. 116 | Write-Verbose "Loading resource strings from: $LiteralPath" 117 | $count = 0 118 | if ($messages = (Get-Content -LiteralPath $LiteralPath -Encoding UTF8 | Out-String | ConvertFrom-Json).messages) { 119 | # Add each resource string to the hashtable. 120 | foreach ($member in (Get-Member -InputObject $messages -MemberType NoteProperty)) { 121 | [string]$key = $member.Name 122 | $script:resourceStrings[$key] = $messages."$key" 123 | $count++ 124 | } 125 | } 126 | 127 | Write-Verbose "Loaded $count strings." 128 | 129 | # Get the culture. 130 | $culture = Get-TaskVariable -Name "System.Culture" -Default "en-US" 131 | 132 | # Load the resjson. 133 | $resjsonPath = "$([System.IO.Path]::GetDirectoryName($LiteralPath))\Strings\resources.resjson\$culture\resources.resjson" 134 | if (Test-Path -LiteralPath $resjsonPath) { 135 | Write-Verbose "Loading resource strings from: $resjsonPath" 136 | $count = 0 137 | $resjson = Get-Content -LiteralPath $resjsonPath -Encoding UTF8 | Out-String | ConvertFrom-Json 138 | foreach ($member in (Get-Member -Name loc.messages.* -InputObject $resjson -MemberType NoteProperty)) { 139 | if (!($value = $resjson."$($member.Name)")) { 140 | continue 141 | } 142 | 143 | [string]$key = $member.Name.Substring('loc.messages.'.Length) 144 | $script:resourceStrings[$key] = $value 145 | $count++ 146 | } 147 | 148 | Write-Verbose "Loaded $count strings." 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/Minimatch.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/Minimatch.dll -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/OutFunctions.ps1: -------------------------------------------------------------------------------- 1 | # TODO: It would be better if the Out-Default function resolved the underlying Out-Default 2 | # command in the begin block. This would allow for supporting other modules that override 3 | # Out-Default. 4 | $script:outDefaultCmdlet = $ExecutionContext.InvokeCommand.GetCmdlet("Microsoft.PowerShell.Core\Out-Default") 5 | 6 | ######################################## 7 | # Public functions. 8 | ######################################## 9 | function Out-Default { 10 | [CmdletBinding(ConfirmImpact = "Medium")] 11 | param( 12 | [Parameter(ValueFromPipeline = $true)] 13 | [System.Management.Automation.PSObject]$InputObject) 14 | 15 | begin { 16 | #Write-Host '[Entering Begin Out-Default]' 17 | $__sp = { & $script:outDefaultCmdlet @PSBoundParameters }.GetSteppablePipeline() 18 | $__sp.Begin($pscmdlet) 19 | #Write-Host '[Leaving Begin Out-Default]' 20 | } 21 | 22 | process { 23 | #Write-Host '[Entering Process Out-Default]' 24 | if ($_ -is [System.Management.Automation.ErrorRecord]) { 25 | Write-Verbose -Message 'Error record:' 4>&1 | Out-Default 26 | Write-Verbose -Message (Remove-TrailingNewLine (Out-String -InputObject $_ -Width 2147483647)) 4>&1 | Out-Default 27 | Write-Verbose -Message 'Script stack trace:' 4>&1 | Out-Default 28 | Write-Verbose -Message "$($_.ScriptStackTrace)" 4>&1 | Out-Default 29 | Write-Verbose -Message 'Exception:' 4>&1 | Out-Default 30 | Write-Verbose -Message $_.Exception.ToString() 4>&1 | Out-Default 31 | Write-TaskError -Message $_.Exception.Message 32 | } elseif ($_ -is [System.Management.Automation.WarningRecord]) { 33 | Write-TaskWarning -Message (Remove-TrailingNewLine (Out-String -InputObject $_ -Width 2147483647)) 34 | } elseif ($_ -is [System.Management.Automation.VerboseRecord] -and !$global:__vstsNoOverrideVerbose) { 35 | foreach ($private:str in (Format-DebugMessage -Object $_)) { 36 | Write-TaskVerbose -Message $private:str 37 | } 38 | } elseif ($_ -is [System.Management.Automation.DebugRecord] -and !$global:__vstsNoOverrideVerbose) { 39 | foreach ($private:str in (Format-DebugMessage -Object $_)) { 40 | Write-TaskDebug -Message $private:str 41 | } 42 | } else { 43 | # TODO: Consider using out-string here to control the width. As a security precaution it would actually be best to set it to max so wrapping doesn't interfere with secret masking. 44 | $__sp.Process($_) 45 | } 46 | 47 | #Write-Host '[Leaving Process Out-Default]' 48 | } 49 | 50 | end { 51 | #Write-Host '[Entering End Out-Default]' 52 | $__sp.End() 53 | #Write-Host '[Leaving End Out-Default]' 54 | } 55 | } 56 | 57 | ######################################## 58 | # Private functions. 59 | ######################################## 60 | function Format-DebugMessage { 61 | [CmdletBinding()] 62 | param([psobject]$Object) 63 | 64 | $private:str = Out-String -InputObject $Object -Width 2147483647 65 | $private:str = Remove-TrailingNewLine $private:str 66 | "$private:str".Replace("`r`n", "`n").Replace("`r", "`n").Split("`n"[0]) 67 | } 68 | 69 | function Remove-TrailingNewLine { 70 | [CmdletBinding()] 71 | param($Str) 72 | if ([object]::ReferenceEquals($Str, $null)) { 73 | return $Str 74 | } elseif ($Str.EndsWith("`r`n")) { 75 | return $Str.Substring(0, $Str.Length - 2) 76 | } else { 77 | return $Str 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/PSGetModuleInfo.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/PSGetModuleInfo.xml -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/Strings/resources.resjson/de-de/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "Agentversion {0} oder höher ist erforderlich.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Der Containerpfad wurde nicht gefunden: \"{0}\".", 4 | "loc.messages.PSLIB_EndpointAuth0": "\"{0}\"-Dienstendpunkt-Anmeldeinformationen", 5 | "loc.messages.PSLIB_EndpointUrl0": "\"{0}\"-Dienstendpunkt-URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Fehler beim Aufzählen von Unterverzeichnissen für den folgenden Pfad: \"{0}\"", 7 | "loc.messages.PSLIB_FileNotFound0": "Die Datei wurde nicht gefunden: \"{0}\".", 8 | "loc.messages.PSLIB_Input0": "\"{0}\"-Eingabe", 9 | "loc.messages.PSLIB_InvalidPattern0": "Ungültiges Muster: \"{0}\"", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Der Blattpfad wurde nicht gefunden: \"{0}\".", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "Fehler bei der Normalisierung bzw. Erweiterung des Pfads. Die Pfadlänge wurde vom Kernel32-Subsystem nicht zurückgegeben für: \"{0}\"", 12 | "loc.messages.PSLIB_PathNotFound0": "Der Pfad wurde nicht gefunden: \"{0}\".", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Der Prozess \"{0}\" wurde mit dem Code \"{1}\" beendet.", 14 | "loc.messages.PSLIB_Required0": "Erforderlich: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Fehler beim Zeichenfolgenformat.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "Der Zeichenfolgen-Ressourcenschlüssel wurde nicht gefunden: \"{0}\".", 17 | "loc.messages.PSLIB_TaskVariable0": "\"{0}\"-Taskvariable" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/Strings/resources.resjson/en-US/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "Agent version {0} or higher is required.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Container path not found: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "'{0}' service endpoint credentials", 5 | "loc.messages.PSLIB_EndpointUrl0": "'{0}' service endpoint URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Enumerating subdirectories failed for path: '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "File not found: '{0}'", 8 | "loc.messages.PSLIB_Input0": "'{0}' input", 9 | "loc.messages.PSLIB_InvalidPattern0": "Invalid pattern: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Leaf path not found: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "Path normalization/expansion failed. The path length was not returned by the Kernel32 subsystem for: '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "Path not found: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Process '{0}' exited with code '{1}'.", 14 | "loc.messages.PSLIB_Required0": "Required: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "String format failed.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "String resource key not found: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "'{0}' task variable" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/Strings/resources.resjson/es-es/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "Se require la versión {0} o posterior del agente.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "No se encuentra la ruta de acceso del contenedor: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "Credenciales del punto de conexión de servicio '{0}'", 5 | "loc.messages.PSLIB_EndpointUrl0": "URL del punto de conexión de servicio '{0}'", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "No se pudieron enumerar los subdirectorios de la ruta de acceso: '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "Archivo no encontrado: '{0}'", 8 | "loc.messages.PSLIB_Input0": "Entrada '{0}'", 9 | "loc.messages.PSLIB_InvalidPattern0": "Patrón no válido: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "No se encuentra la ruta de acceso de la hoja: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "No se pudo normalizar o expandir la ruta de acceso. El subsistema Kernel32 no devolvió la longitud de la ruta de acceso para: '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "No se encuentra la ruta de acceso: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "El proceso '{0}' finalizó con el código '{1}'.", 14 | "loc.messages.PSLIB_Required0": "Se requiere: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Error de formato de cadena.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "No se encuentra la clave de recurso de la cadena: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "Variable de tarea '{0}'" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/Strings/resources.resjson/fr-fr/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "L'agent version {0} (ou une version ultérieure) est obligatoire.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Le chemin du conteneur est introuvable : '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "Informations d'identification du point de terminaison de service '{0}'", 5 | "loc.messages.PSLIB_EndpointUrl0": "URL du point de terminaison de service '{0}'", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Échec de l'énumération des sous-répertoires pour le chemin : '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "Fichier introuvable : {0}.", 8 | "loc.messages.PSLIB_Input0": "Entrée '{0}'", 9 | "loc.messages.PSLIB_InvalidPattern0": "Modèle non valide : '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Le chemin feuille est introuvable : '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "Échec de la normalisation/l'expansion du chemin. La longueur du chemin n'a pas été retournée par le sous-système Kernel32 pour : '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "Chemin introuvable : '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Le processus '{0}' s'est arrêté avec le code '{1}'.", 14 | "loc.messages.PSLIB_Required0": "Obligatoire : {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Échec du format de la chaîne.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "Clé de la ressource de type chaîne introuvable : '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "Variable de tâche '{0}'" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/Strings/resources.resjson/it-IT/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "È richiesta la versione dell'agente {0} o superiore.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Percorso del contenitore non trovato: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "Credenziali dell'endpoint servizio '{0}'", 5 | "loc.messages.PSLIB_EndpointUrl0": "URL dell'endpoint servizio '{0}'", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "L'enumerazione delle sottodirectory per il percorso '{0}' non è riuscita", 7 | "loc.messages.PSLIB_FileNotFound0": "File non trovato: '{0}'", 8 | "loc.messages.PSLIB_Input0": "Input di '{0}'", 9 | "loc.messages.PSLIB_InvalidPattern0": "Criterio non valido: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Percorso foglia non trovato: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "La normalizzazione o l'espansione del percorso non è riuscita. Il sottosistema Kernel32 non ha restituito la lunghezza del percorso per '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "Percorso non trovato: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Il processo '{0}' è stato terminato ed è stato restituito il codice '{1}'.", 14 | "loc.messages.PSLIB_Required0": "Obbligatorio: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Errore nel formato della stringa.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "La chiave della risorsa stringa non è stata trovata: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "Variabile dell'attività '{0}'" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/Strings/resources.resjson/ja-jp/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "バージョン {0} 以降のエージェントが必要です。", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "コンテナーのパスが見つかりません: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "'{0}' サービス エンドポイントの資格情報", 5 | "loc.messages.PSLIB_EndpointUrl0": "'{0}' サービス エンドポイントの URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "パス '{0}' のサブディレクトリを列挙できませんでした", 7 | "loc.messages.PSLIB_FileNotFound0": "ファイルが見つかりません: '{0}'", 8 | "loc.messages.PSLIB_Input0": "'{0}' 入力", 9 | "loc.messages.PSLIB_InvalidPattern0": "使用できないパターンです: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "リーフ パスが見つかりません: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "パスの正規化/展開に失敗しました。Kernel32 サブシステムからパス '{0}' の長さが返されませんでした", 12 | "loc.messages.PSLIB_PathNotFound0": "パスが見つかりません: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "プロセス '{0}' がコード '{1}' で終了しました。", 14 | "loc.messages.PSLIB_Required0": "必要: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "文字列のフォーマットに失敗しました。", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "文字列のリソース キーが見つかりません: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "'{0}' タスク変数" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/Strings/resources.resjson/ko-KR/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "에이전트 버전 {0} 이상이 필요합니다.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "컨테이너 경로를 찾을 수 없음: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "'{0}' 서비스 끝점 자격 증명", 5 | "loc.messages.PSLIB_EndpointUrl0": "'{0}' 서비스 끝점 URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "경로에 대해 하위 디렉터리를 열거하지 못함: '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "{0} 파일을 찾을 수 없습니다.", 8 | "loc.messages.PSLIB_Input0": "'{0}' 입력", 9 | "loc.messages.PSLIB_InvalidPattern0": "잘못된 패턴: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Leaf 경로를 찾을 수 없음: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "경로 정규화/확장에 실패했습니다. 다음에 대해 Kernel32 subsystem에서 경로 길이를 반환하지 않음: '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "경로를 찾을 수 없음: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "'{1}' 코드로 '{0}' 프로세스가 종료되었습니다.", 14 | "loc.messages.PSLIB_Required0": "필수: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "문자열을 포맷하지 못했습니다.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "문자열 리소스 키를 찾을 수 없음: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "'{0}' 작업 변수" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/Strings/resources.resjson/ru-RU/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "Требуется версия агента {0} или более поздняя.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Путь к контейнеру не найден: \"{0}\".", 4 | "loc.messages.PSLIB_EndpointAuth0": "Учетные данные конечной точки службы \"{0}\"", 5 | "loc.messages.PSLIB_EndpointUrl0": "URL-адрес конечной точки службы \"{0}\"", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Сбой перечисления подкаталогов для пути: \"{0}\".", 7 | "loc.messages.PSLIB_FileNotFound0": "Файл не найден: \"{0}\".", 8 | "loc.messages.PSLIB_Input0": "Входные данные \"{0}\".", 9 | "loc.messages.PSLIB_InvalidPattern0": "Недопустимый шаблон: \"{0}\".", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Путь к конечному объекту не найден: \"{0}\".", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "Сбой нормализации и расширения пути. Длина пути не была возвращена подсистемой Kernel32 для: \"{0}\".", 12 | "loc.messages.PSLIB_PathNotFound0": "Путь не найден: \"{0}\".", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Процесс \"{0}\" завершил работу с кодом \"{1}\".", 14 | "loc.messages.PSLIB_Required0": "Требуется: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Сбой формата строки.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "Ключ ресурса строки не найден: \"{0}\".", 17 | "loc.messages.PSLIB_TaskVariable0": "Переменная задачи \"{0}\"" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/Strings/resources.resjson/zh-CN/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "需要代理版本 {0} 或更高版本。", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "找不到容器路径:“{0}”", 4 | "loc.messages.PSLIB_EndpointAuth0": "“{0}”服务终结点凭据", 5 | "loc.messages.PSLIB_EndpointUrl0": "“{0}”服务终结点 URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "枚举路径的子目录失败:“{0}”", 7 | "loc.messages.PSLIB_FileNotFound0": "找不到文件: {0}。", 8 | "loc.messages.PSLIB_Input0": "“{0}”输入", 9 | "loc.messages.PSLIB_InvalidPattern0": "无效的模式:“{0}”", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "找不到叶路径:“{0}”", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "路径规范化/扩展失败。路径长度不是由“{0}”的 Kernel32 子系统返回的", 12 | "loc.messages.PSLIB_PathNotFound0": "找不到路径:“{0}”", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "过程“{0}”已退出,代码为“{1}”。", 14 | "loc.messages.PSLIB_Required0": "必需: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "字符串格式无效。", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "找不到字符串资源关键字:“{0}”", 17 | "loc.messages.PSLIB_TaskVariable0": "“{0}”任务变量" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/Strings/resources.resjson/zh-TW/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "需要代理程式版本 {0} 或更新的版本。", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "找不到容器路徑: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "'{0}' 服務端點認證", 5 | "loc.messages.PSLIB_EndpointUrl0": "'{0}' 服務端點 URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "為路徑列舉子目錄失敗: '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "找不到檔案: '{0}'", 8 | "loc.messages.PSLIB_Input0": "'{0}' 輸入", 9 | "loc.messages.PSLIB_InvalidPattern0": "模式無效: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "找不到分葉路徑: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "路徑正規化/展開失敗。Kernel32 子系統未傳回 '{0}' 的路徑長度", 12 | "loc.messages.PSLIB_PathNotFound0": "找不到路徑: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "處理序 '{0}' 以返回碼 '{1}' 結束。", 14 | "loc.messages.PSLIB_Required0": "必要項: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "字串格式失敗。", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "找不到字串資源索引鍵: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "'{0}' 工作變數" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/ToolFunctions.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Asserts the agent version is at least the specified minimum. 4 | 5 | .PARAMETER Minimum 6 | Minimum version - must be 2.104.1 or higher. 7 | #> 8 | function Assert-Agent { 9 | [CmdletBinding()] 10 | param( 11 | [Parameter(Mandatory = $true)] 12 | [version]$Minimum) 13 | 14 | if (([version]'2.104.1').CompareTo($Minimum) -ge 1) { 15 | Write-Error "Assert-Agent requires the parameter to be 2.104.1 or higher." 16 | return 17 | } 18 | 19 | $agent = Get-TaskVariable -Name 'agent.version' 20 | if (!$agent -or $Minimum.CompareTo([version]$agent) -ge 1) { 21 | Write-Error (Get-LocString -Key 'PSLIB_AgentVersion0Required' -ArgumentList $Minimum) 22 | } 23 | } 24 | 25 | <# 26 | .SYNOPSIS 27 | Asserts that a path exists. Throws if the path does not exist. 28 | 29 | .PARAMETER PassThru 30 | True to return the path. 31 | #> 32 | function Assert-Path { 33 | [CmdletBinding()] 34 | param( 35 | [Parameter(Mandatory = $true)] 36 | [string]$LiteralPath, 37 | [Microsoft.PowerShell.Commands.TestPathType]$PathType = [Microsoft.PowerShell.Commands.TestPathType]::Any, 38 | [switch]$PassThru) 39 | 40 | if ($PathType -eq [Microsoft.PowerShell.Commands.TestPathType]::Any) { 41 | Write-Verbose "Asserting path exists: '$LiteralPath'" 42 | } else { 43 | Write-Verbose "Asserting $("$PathType".ToLowerInvariant()) path exists: '$LiteralPath'" 44 | } 45 | 46 | if (Test-Path -LiteralPath $LiteralPath -PathType $PathType) { 47 | if ($PassThru) { 48 | return $LiteralPath 49 | } 50 | 51 | return 52 | } 53 | 54 | $resourceKey = switch ($PathType) { 55 | ([Microsoft.PowerShell.Commands.TestPathType]::Container) { "PSLIB_ContainerPathNotFound0" ; break } 56 | ([Microsoft.PowerShell.Commands.TestPathType]::Leaf) { "PSLIB_LeafPathNotFound0" ; break } 57 | default { "PSLIB_PathNotFound0" } 58 | } 59 | 60 | throw (Get-LocString -Key $resourceKey -ArgumentList $LiteralPath) 61 | } 62 | 63 | <# 64 | .SYNOPSIS 65 | Executes an external program. 66 | 67 | .DESCRIPTION 68 | Executes an external program and waits for the process to exit. 69 | 70 | After calling this command, the exit code of the process can be retrieved from the variable $LASTEXITCODE. 71 | 72 | .PARAMETER Encoding 73 | This parameter not required for most scenarios. Indicates how to interpret the encoding from the external program. An example use case would be if an external program outputs UTF-16 XML and the output needs to be parsed. 74 | 75 | .PARAMETER RequireExitCodeZero 76 | Indicates whether to write an error to the error pipeline if the exit code is not zero. 77 | #> 78 | function Invoke-Tool { # TODO: RENAME TO INVOKE-PROCESS? 79 | [CmdletBinding()] 80 | param( 81 | [ValidatePattern('^[^\r\n]*$')] 82 | [Parameter(Mandatory = $true)] 83 | [string]$FileName, 84 | [ValidatePattern('^[^\r\n]*$')] 85 | [Parameter()] 86 | [string]$Arguments, 87 | [string]$WorkingDirectory, 88 | [System.Text.Encoding]$Encoding, 89 | [switch]$RequireExitCodeZero) 90 | 91 | Trace-EnteringInvocation $MyInvocation 92 | $isPushed = $false 93 | $originalEncoding = $null 94 | try { 95 | if ($Encoding) { 96 | $originalEncoding = [System.Console]::OutputEncoding 97 | [System.Console]::OutputEncoding = $Encoding 98 | } 99 | 100 | if ($WorkingDirectory) { 101 | Push-Location -LiteralPath $WorkingDirectory -ErrorAction Stop 102 | $isPushed = $true 103 | } 104 | 105 | $FileName = $FileName.Replace('"', '').Replace("'", "''") 106 | Write-Host "##[command]""$FileName"" $Arguments" 107 | Invoke-Expression "& '$FileName' --% $Arguments" 108 | Write-Verbose "Exit code: $LASTEXITCODE" 109 | if ($RequireExitCodeZero -and $LASTEXITCODE -ne 0) { 110 | Write-Error (Get-LocString -Key PSLIB_Process0ExitedWithCode1 -ArgumentList ([System.IO.Path]::GetFileName($FileName)), $LASTEXITCODE) 111 | } 112 | } finally { 113 | if ($originalEncoding) { 114 | [System.Console]::OutputEncoding = $originalEncoding 115 | } 116 | 117 | if ($isPushed) { 118 | Pop-Location 119 | } 120 | 121 | Trace-LeavingInvocation $MyInvocation 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/TraceFunctions.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Writes verbose information about the invocation being entered. 4 | 5 | .DESCRIPTION 6 | Used to trace verbose information when entering a function/script. Writes an entering message followed by a short description of the invocation. Additionally each bound parameter and unbound argument is also traced. 7 | 8 | .PARAMETER Parameter 9 | Wildcard pattern to control which bound parameters are traced. 10 | #> 11 | function Trace-EnteringInvocation { 12 | [CmdletBinding()] 13 | param( 14 | [Parameter(Mandatory = $true)] 15 | [System.Management.Automation.InvocationInfo]$InvocationInfo, 16 | [string[]]$Parameter = '*') 17 | 18 | Write-Verbose "Entering $(Get-InvocationDescription $InvocationInfo)." 19 | $OFS = ", " 20 | if ($InvocationInfo.BoundParameters.Count -and $Parameter.Count) { 21 | if ($Parameter.Count -eq 1 -and $Parameter[0] -eq '*') { 22 | # Trace all parameters. 23 | foreach ($key in $InvocationInfo.BoundParameters.Keys) { 24 | Write-Verbose " $($key): '$($InvocationInfo.BoundParameters[$key])'" 25 | } 26 | } else { 27 | # Trace matching parameters. 28 | foreach ($key in $InvocationInfo.BoundParameters.Keys) { 29 | foreach ($p in $Parameter) { 30 | if ($key -like $p) { 31 | Write-Verbose " $($key): '$($InvocationInfo.BoundParameters[$key])'" 32 | break 33 | } 34 | } 35 | } 36 | } 37 | } 38 | 39 | # Trace all unbound arguments. 40 | if (@($InvocationInfo.UnboundArguments).Count) { 41 | for ($i = 0 ; $i -lt $InvocationInfo.UnboundArguments.Count ; $i++) { 42 | Write-Verbose " args[$i]: '$($InvocationInfo.UnboundArguments[$i])'" 43 | } 44 | } 45 | } 46 | 47 | <# 48 | .SYNOPSIS 49 | Writes verbose information about the invocation being left. 50 | 51 | .DESCRIPTION 52 | Used to trace verbose information when leaving a function/script. Writes a leaving message followed by a short description of the invocation. 53 | #> 54 | function Trace-LeavingInvocation { 55 | [CmdletBinding()] 56 | param( 57 | [Parameter(Mandatory = $true)] 58 | [System.Management.Automation.InvocationInfo]$InvocationInfo) 59 | 60 | Write-Verbose "Leaving $(Get-InvocationDescription $InvocationInfo)." 61 | } 62 | 63 | <# 64 | .SYNOPSIS 65 | Writes verbose information about paths. 66 | 67 | .DESCRIPTION 68 | Writes verbose information about the paths. The paths are sorted and a the common root is written only once, followed by each relative path. 69 | 70 | .PARAMETER PassThru 71 | Indicates whether to return the sorted paths. 72 | #> 73 | function Trace-Path { 74 | [CmdletBinding()] 75 | param( 76 | [string[]]$Path, 77 | [switch]$PassThru) 78 | 79 | if ($Path.Count -eq 0) { 80 | Write-Verbose "No paths." 81 | if ($PassThru) { 82 | $Path 83 | } 84 | } elseif ($Path.Count -eq 1) { 85 | Write-Verbose "Path: $($Path[0])" 86 | if ($PassThru) { 87 | $Path 88 | } 89 | } else { 90 | # Find the greatest common root. 91 | $sorted = $Path | Sort-Object 92 | $firstPath = $sorted[0].ToCharArray() 93 | $lastPath = $sorted[-1].ToCharArray() 94 | $commonEndIndex = 0 95 | $j = if ($firstPath.Length -lt $lastPath.Length) { $firstPath.Length } else { $lastPath.Length } 96 | for ($i = 0 ; $i -lt $j ; $i++) { 97 | if ($firstPath[$i] -eq $lastPath[$i]) { 98 | if ($firstPath[$i] -eq '\') { 99 | $commonEndIndex = $i 100 | } 101 | } else { 102 | break 103 | } 104 | } 105 | 106 | if ($commonEndIndex -eq 0) { 107 | # No common root. 108 | Write-Verbose "Paths:" 109 | foreach ($p in $sorted) { 110 | Write-Verbose " $p" 111 | } 112 | } else { 113 | Write-Verbose "Paths: $($Path[0].Substring(0, $commonEndIndex + 1))" 114 | foreach ($p in $sorted) { 115 | Write-Verbose " $($p.Substring($commonEndIndex + 1))" 116 | } 117 | } 118 | 119 | if ($PassThru) { 120 | $sorted 121 | } 122 | } 123 | } 124 | 125 | ######################################## 126 | # Private functions. 127 | ######################################## 128 | function Get-InvocationDescription { 129 | [CmdletBinding()] 130 | param([System.Management.Automation.InvocationInfo]$InvocationInfo) 131 | 132 | if ($InvocationInfo.MyCommand.Path) { 133 | $InvocationInfo.MyCommand.Path 134 | } elseif ($InvocationInfo.MyCommand.Name) { 135 | $InvocationInfo.MyCommand.Name 136 | } else { 137 | $InvocationInfo.MyCommand.CommandType 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/VstsTaskSdk.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/VstsTaskSdk.dll -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/VstsTaskSdk.psd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/VstsTaskSdk.psd1 -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/VstsTaskSdk.psm1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | [ValidateNotNull()] 4 | [Parameter()] 5 | [hashtable]$ModuleParameters = @{ }) 6 | 7 | if ($host.Name -ne 'ConsoleHost') { 8 | Write-Warning "VstsTaskSdk is designed for use with powershell.exe (ConsoleHost). Output may be different when used with other hosts." 9 | } 10 | 11 | # Private module variables. 12 | [bool]$script:nonInteractive = "$($ModuleParameters['NonInteractive'])" -eq 'true' 13 | Write-Verbose "NonInteractive: $script:nonInteractive" 14 | 15 | # VstsTaskSdk.dll contains the TerminationException and NativeMethods for handle long path 16 | # We used to do inline C# in this powershell module 17 | # However when csc compile the inline C#, it will hit process env block size limit since it's not use unicode to encode env 18 | # To solve the env block size problem, we choose to put all inline C# into an assembly VstsTaskSdk.dll, signing it, package with the PS modules. 19 | Write-Verbose "Loading compiled helper $PSScriptRoot\VstsTaskSdk.dll." 20 | Add-Type -LiteralPath $PSScriptRoot\VstsTaskSdk.dll 21 | 22 | # Import/export functions. 23 | . "$PSScriptRoot\FindFunctions.ps1" 24 | . "$PSScriptRoot\InputFunctions.ps1" 25 | . "$PSScriptRoot\LegacyFindFunctions.ps1" 26 | . "$PSScriptRoot\LocalizationFunctions.ps1" 27 | . "$PSScriptRoot\LoggingCommandFunctions.ps1" 28 | . "$PSScriptRoot\LongPathFunctions.ps1" 29 | . "$PSScriptRoot\ServerOMFunctions.ps1" 30 | . "$PSScriptRoot\ToolFunctions.ps1" 31 | . "$PSScriptRoot\TraceFunctions.ps1" 32 | . "$PSScriptRoot\OutFunctions.ps1" # Load the out functions after all of the other functions are loaded. 33 | Export-ModuleMember -Function @( 34 | # Find functions. 35 | 'Find-Match' 36 | 'New-FindOptions' 37 | 'New-MatchOptions' 38 | 'Select-Match' 39 | # Input functions. 40 | 'Get-Endpoint' 41 | 'Get-SecureFileTicket' 42 | 'Get-SecureFileName' 43 | 'Get-Input' 44 | 'Get-TaskVariable' 45 | 'Get-TaskVariableInfo' 46 | 'Set-TaskVariable' 47 | # Legacy find functions. 48 | 'Find-Files' 49 | # Localization functions. 50 | 'Get-LocString' 51 | 'Import-LocStrings' 52 | # Logging command functions. 53 | 'Write-AddAttachment' 54 | 'Write-AddBuildTag' 55 | 'Write-AssociateArtifact' 56 | 'Write-LogDetail' 57 | 'Write-PrependPath' 58 | 'Write-SetEndpoint' 59 | 'Write-SetProgress' 60 | 'Write-SetResult' 61 | 'Write-SetSecret' 62 | 'Write-SetVariable' 63 | 'Write-TaskDebug' 64 | 'Write-TaskError' 65 | 'Write-TaskVerbose' 66 | 'Write-TaskWarning' 67 | 'Write-UpdateBuildNumber' 68 | 'Write-UpdateReleaseName' 69 | 'Write-UploadArtifact' 70 | 'Write-UploadBuildLog' 71 | 'Write-UploadFile' 72 | 'Write-UploadSummary' 73 | # Out functions. 74 | 'Out-Default' 75 | # Server OM functions. 76 | 'Get-AssemblyReference' 77 | 'Get-TfsClientCredentials' 78 | 'Get-TfsService' 79 | 'Get-VssCredentials' 80 | 'Get-VssHttpClient' 81 | # Tool functions. 82 | 'Assert-Agent' 83 | 'Assert-Path' 84 | 'Invoke-Tool' 85 | # Trace functions. 86 | 'Trace-EnteringInvocation' 87 | 'Trace-LeavingInvocation' 88 | 'Trace-Path' 89 | # Proxy functions 90 | 'Get-WebProxy' 91 | # Client cert functions 92 | 'Get-ClientCertificate' 93 | ) 94 | 95 | # Override Out-Default globally. 96 | $null = New-Item -Force -Path "function:\global:Out-Default" -Value (Get-Command -CommandType Function -Name Out-Default -ListImported) 97 | New-Alias -Name Out-Default -Value "global:Out-Default" -Scope global 98 | 99 | # Perform some initialization in a script block to enable merging the pipelines. 100 | $scriptText = @" 101 | # Load the SDK resource strings. 102 | Import-LocStrings "$PSScriptRoot\lib.json" 103 | 104 | # Load the module that contains ConvertTo-SecureString. 105 | if (!(Get-Module -Name Microsoft.PowerShell.Security)) { 106 | Write-Verbose "Importing the module 'Microsoft.PowerShell.Security'." 107 | Import-Module -Name Microsoft.PowerShell.Security 2>&1 | 108 | ForEach-Object { 109 | if (`$_ -is [System.Management.Automation.ErrorRecord]) { 110 | Write-Verbose `$_.Exception.Message 111 | } else { 112 | ,`$_ 113 | } 114 | } 115 | } 116 | "@ 117 | . ([scriptblock]::Create($scriptText)) 2>&1 3>&1 4>&1 5>&1 | Out-Default 118 | 119 | # Create Invoke-VstsTaskScript in a special way so it is not bound to the module. 120 | # Otherwise calling the task script block would run within the module context. 121 | # 122 | # An alternative way to solve the problem is to close the script block (i.e. closure). 123 | # However, that introduces a different problem. Closed script blocks are created within 124 | # a dynamic module. Each module gets it's own session state separate from the global 125 | # session state. When running in a regular script context, Import-Module calls import 126 | # the target module into the global session state. When running in a module context, 127 | # Import-Module calls import the target module into the caller module's session state. 128 | # 129 | # The goal of a task may include executing ad-hoc scripts. Therefore, task scripts 130 | # should run in regular script context. The end user specifying an ad-hoc script expects 131 | # the module import rules to be consistent with the default behavior (i.e. imported 132 | # into the global session state). 133 | $null = New-Item -Force -Path "function:\global:Invoke-VstsTaskScript" -Value ([scriptblock]::Create(@' 134 | [CmdletBinding()] 135 | param( 136 | [Parameter(Mandatory = $true)] 137 | [scriptblock]$ScriptBlock) 138 | 139 | try { 140 | $global:ErrorActionPreference = 'Stop' 141 | 142 | # Initialize the environment. 143 | $vstsModule = Get-Module -Name VstsTaskSdk 144 | Write-Verbose "$($vstsModule.Name) $($vstsModule.Version) commit $($vstsModule.PrivateData.PSData.CommitHash)" 4>&1 | Out-Default 145 | & $vstsModule Initialize-Inputs 4>&1 | Out-Default 146 | 147 | # Remove the local variable before calling the user's script. 148 | Remove-Variable -Name vstsModule 149 | 150 | # Call the user's script. 151 | $ScriptBlock | 152 | ForEach-Object { 153 | # Remove the scriptblock variable before calling it. 154 | Remove-Variable -Name ScriptBlock 155 | & $_ 2>&1 3>&1 4>&1 5>&1 | Out-Default 156 | } 157 | } catch [VstsTaskSdk.TerminationException] { 158 | # Special internal exception type to control the flow. Not currently intended 159 | # for public usage and subject to change. 160 | $global:__vstsNoOverrideVerbose = '' 161 | Write-Verbose "Task script terminated." 4>&1 | Out-Default 162 | } catch { 163 | $global:__vstsNoOverrideVerbose = '' 164 | Write-Verbose "Caught exception from task script." 4>&1 | Out-Default 165 | $_ | Out-Default 166 | Write-Host "##vso[task.complete result=Failed]" 167 | } 168 | '@)) 169 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/ps_modules/VstsTaskSdk/lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "messages": { 3 | "PSLIB_AgentVersion0Required": "Agent version {0} or higher is required.", 4 | "PSLIB_ContainerPathNotFound0": "Container path not found: '{0}'", 5 | "PSLIB_EndpointAuth0": "'{0}' service endpoint credentials", 6 | "PSLIB_EndpointUrl0": "'{0}' service endpoint URL", 7 | "PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Enumerating subdirectories failed for path: '{0}'", 8 | "PSLIB_FileNotFound0": "File not found: '{0}'", 9 | "PSLIB_Input0": "'{0}' input", 10 | "PSLIB_InvalidPattern0": "Invalid pattern: '{0}'", 11 | "PSLIB_LeafPathNotFound0": "Leaf path not found: '{0}'", 12 | "PSLIB_PathLengthNotReturnedFor0": "Path normalization/expansion failed. The path length was not returned by the Kernel32 subsystem for: '{0}'", 13 | "PSLIB_PathNotFound0": "Path not found: '{0}'", 14 | "PSLIB_Process0ExitedWithCode1": "Process '{0}' exited with code '{1}'.", 15 | "PSLIB_Required0": "Required: {0}", 16 | "PSLIB_StringFormatFailed": "String format failed.", 17 | "PSLIB_StringResourceKeyNotFound0": "String resource key not found: '{0}'", 18 | "PSLIB_TaskVariable0": "'{0}' task variable" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV2/task.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "7dad075d-a817-45ac-baab-4c1376d2885e", 3 | "name": "WindowsServiceManager", 4 | "friendlyName": "Windows Service Manager", 5 | "description": "Deploys a Windows Service to an Agent or a Deployment Group Target using WinRM.", 6 | "helpMarkDown": "", 7 | "category": "Utility", 8 | "visibility": [ 9 | "Build", 10 | "Release" 11 | ], 12 | "author": "MDSolutions", 13 | "version": { 14 | "Major": 2, 15 | "Minor": 2, 16 | "Patch": 2 17 | }, 18 | "instanceNameFormat": "Deploy Windows Service", 19 | "groups": [ 20 | { 21 | "name": "advanced", 22 | "displayName": "Advanced", 23 | "isExpanded": true 24 | } 25 | ], 26 | "inputs": [ 27 | { 28 | "name": "DeploymentType", 29 | "type": "radio", 30 | "label": "Deployment Type", 31 | "required": true, 32 | "defaultValue": "Agent", 33 | "helpMarkDown": "Deploy with an Agent or a Deployment Group.", 34 | "options": { 35 | "Agent": "Agent", 36 | "DeploymentGroup": "Deployment Group" 37 | } 38 | }, 39 | { 40 | "name": "Machines", 41 | "label": "Machines", 42 | "required": true, 43 | "helpMarkDown": "Provide a comma separated list of machine IP addresses or FQDNs. Or provide output variable of other tasks. Eg: $(variableName).", 44 | "visibleRule": "DeploymentType=Agent" 45 | }, 46 | { 47 | "name": "AdminLogin", 48 | "label": "Admin Login", 49 | "required": true, 50 | "helpMarkDown": "Administrator login for the target machines.", 51 | "visibleRule": "DeploymentType=Agent" 52 | }, 53 | { 54 | "name": "Password", 55 | "label": "Password", 56 | "required": true, 57 | "helpMarkDown": "Password for administrator login for the target machines. It can accept variable defined in Build/Release definitions as '$(passwordVariable)'. You may mark variable type as 'secret' to secure it.", 58 | "visibleRule": "DeploymentType=Agent" 59 | }, 60 | { 61 | "name": "ServiceName", 62 | "type": "string", 63 | "label": "Service Name", 64 | "defaultValue": "", 65 | "required": true, 66 | "helpMarkDown": "The exact name of the windows service installed on the deployment group target." 67 | }, 68 | { 69 | "name": "ArtifactPath", 70 | "type": "filePath", 71 | "label": "Artifact Path", 72 | "defaultValue": "", 73 | "required": true, 74 | "helpMarkDown": "The path to the windows service artifact." 75 | }, 76 | { 77 | "name": "TimeOut", 78 | "type": "string", 79 | "label": "Timeout", 80 | "defaultValue": "30", 81 | "required": true, 82 | "helpMarkDown": "The number of seconds to wait for the service to stop." 83 | }, 84 | { 85 | "name": "StopProcess", 86 | "type": "boolean", 87 | "label": "Stop Process", 88 | "defaultValue": false, 89 | "groupName": "advanced", 90 | "helpMarkDown": "Stops the process if the service does not respond within the timeout limit." 91 | }, 92 | { 93 | "name": "CleanInstall", 94 | "type": "boolean", 95 | "label": "Clean Install", 96 | "defaultValue": false, 97 | "groupName": "advanced", 98 | "helpMarkDown": "Deletes all files from the Windows Service parent directory prior to deployment of the artifact." 99 | } 100 | ], 101 | "execution": { 102 | "PowerShell3": { 103 | "target": "DeployWindowsService.ps1", 104 | "workingDirectory": "$(currentDirectory)" 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV3/icon.png -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/LocalizationFunctions.ps1: -------------------------------------------------------------------------------- 1 | $script:resourceStrings = @{ } 2 | 3 | <# 4 | .SYNOPSIS 5 | Gets a localized resource string. 6 | 7 | .DESCRIPTION 8 | Gets a localized resource string and optionally formats the string with arguments. 9 | 10 | If the format fails (due to a bad format string or incorrect expected arguments in the format string), then the format string is returned followed by each of the arguments (delimited by a space). 11 | 12 | If the lookup key is not found, then the lookup key is returned followed by each of the arguments (delimited by a space). 13 | 14 | .PARAMETER Require 15 | Writes an error to the error pipeline if the endpoint is not found. 16 | #> 17 | function Get-LocString { 18 | [CmdletBinding()] 19 | param( 20 | [Parameter(Mandatory = $true, Position = 1)] 21 | [string]$Key, 22 | [Parameter(Position = 2)] 23 | [object[]]$ArgumentList = @( )) 24 | 25 | # Due to the dynamically typed nature of PowerShell, a single null argument passed 26 | # to an array parameter is interpreted as a null array. 27 | if ([object]::ReferenceEquals($null, $ArgumentList)) { 28 | $ArgumentList = @( $null ) 29 | } 30 | 31 | # Lookup the format string. 32 | $format = '' 33 | if (!($format = $script:resourceStrings[$Key])) { 34 | # Warn the key was not found. Prevent recursion if the lookup key is the 35 | # "string resource key not found" lookup key. 36 | $resourceNotFoundKey = 'PSLIB_StringResourceKeyNotFound0' 37 | if ($key -ne $resourceNotFoundKey) { 38 | Write-Warning (Get-LocString -Key $resourceNotFoundKey -ArgumentList $Key) 39 | } 40 | 41 | # Fallback to just the key itself if there aren't any arguments to format. 42 | if (!$ArgumentList.Count) { return $key } 43 | 44 | # Otherwise fallback to the key followed by the arguments. 45 | $OFS = " " 46 | return "$key $ArgumentList" 47 | } 48 | 49 | # Return the string if there aren't any arguments to format. 50 | if (!$ArgumentList.Count) { return $format } 51 | 52 | try { 53 | [string]::Format($format, $ArgumentList) 54 | } catch { 55 | Write-Warning (Get-LocString -Key 'PSLIB_StringFormatFailed') 56 | $OFS = " " 57 | "$format $ArgumentList" 58 | } 59 | } 60 | 61 | <# 62 | .SYNOPSIS 63 | Imports resource strings for use with Get-VstsLocString. 64 | 65 | .DESCRIPTION 66 | Imports resource strings for use with Get-VstsLocString. The imported strings are stored in an internal resource string dictionary. Optionally, if a separate resource file for the current culture exists, then the localized strings from that file then imported (overlaid) into the same internal resource string dictionary. 67 | 68 | Resource strings from the SDK are prefixed with "PSLIB_". This prefix should be avoided for custom resource strings. 69 | 70 | .Parameter LiteralPath 71 | JSON file containing resource strings. 72 | 73 | .EXAMPLE 74 | Import-VstsLocStrings -LiteralPath $PSScriptRoot\Task.json 75 | 76 | Imports strings from messages section in the JSON file. If a messages section is not defined, then no strings are imported. Example messages section: 77 | { 78 | "messages": { 79 | "Hello": "Hello you!", 80 | "Hello0": "Hello {0}!" 81 | } 82 | } 83 | 84 | .EXAMPLE 85 | Import-VstsLocStrings -LiteralPath $PSScriptRoot\Task.json 86 | 87 | Overlays strings from an optional separate resource file for the current culture. 88 | 89 | Given the task variable System.Culture is set to 'de-DE'. This variable is set by the agent based on the current culture for the job. 90 | Given the file Task.json contains: 91 | { 92 | "messages": { 93 | "GoodDay": "Good day!", 94 | } 95 | } 96 | Given the file resources.resjson\de-DE\resources.resjson: 97 | { 98 | "loc.messages.GoodDay": "Guten Tag!" 99 | } 100 | 101 | The net result from the import command would be one new key-value pair added to the internal dictionary: Key = 'GoodDay', Value = 'Guten Tag!' 102 | #> 103 | function Import-LocStrings { 104 | [CmdletBinding()] 105 | param( 106 | [Parameter(Mandatory = $true)] 107 | [string]$LiteralPath) 108 | 109 | # Validate the file exists. 110 | if (!(Test-Path -LiteralPath $LiteralPath -PathType Leaf)) { 111 | Write-Warning (Get-LocString -Key PSLIB_FileNotFound0 -ArgumentList $LiteralPath) 112 | return 113 | } 114 | 115 | # Load the json. 116 | Write-Verbose "Loading resource strings from: $LiteralPath" 117 | $count = 0 118 | if ($messages = (Get-Content -LiteralPath $LiteralPath -Encoding UTF8 | Out-String | ConvertFrom-Json).messages) { 119 | # Add each resource string to the hashtable. 120 | foreach ($member in (Get-Member -InputObject $messages -MemberType NoteProperty)) { 121 | [string]$key = $member.Name 122 | $script:resourceStrings[$key] = $messages."$key" 123 | $count++ 124 | } 125 | } 126 | 127 | Write-Verbose "Loaded $count strings." 128 | 129 | # Get the culture. 130 | $culture = Get-TaskVariable -Name "System.Culture" -Default "en-US" 131 | 132 | # Load the resjson. 133 | $resjsonPath = "$([System.IO.Path]::GetDirectoryName($LiteralPath))\Strings\resources.resjson\$culture\resources.resjson" 134 | if (Test-Path -LiteralPath $resjsonPath) { 135 | Write-Verbose "Loading resource strings from: $resjsonPath" 136 | $count = 0 137 | $resjson = Get-Content -LiteralPath $resjsonPath -Encoding UTF8 | Out-String | ConvertFrom-Json 138 | foreach ($member in (Get-Member -Name loc.messages.* -InputObject $resjson -MemberType NoteProperty)) { 139 | if (!($value = $resjson."$($member.Name)")) { 140 | continue 141 | } 142 | 143 | [string]$key = $member.Name.Substring('loc.messages.'.Length) 144 | $script:resourceStrings[$key] = $value 145 | $count++ 146 | } 147 | 148 | Write-Verbose "Loaded $count strings." 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/Minimatch.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/Minimatch.dll -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/OutFunctions.ps1: -------------------------------------------------------------------------------- 1 | # TODO: It would be better if the Out-Default function resolved the underlying Out-Default 2 | # command in the begin block. This would allow for supporting other modules that override 3 | # Out-Default. 4 | $script:outDefaultCmdlet = $ExecutionContext.InvokeCommand.GetCmdlet("Microsoft.PowerShell.Core\Out-Default") 5 | 6 | ######################################## 7 | # Public functions. 8 | ######################################## 9 | function Out-Default { 10 | [CmdletBinding(ConfirmImpact = "Medium")] 11 | param( 12 | [Parameter(ValueFromPipeline = $true)] 13 | [System.Management.Automation.PSObject]$InputObject) 14 | 15 | begin { 16 | #Write-Host '[Entering Begin Out-Default]' 17 | $__sp = { & $script:outDefaultCmdlet @PSBoundParameters }.GetSteppablePipeline() 18 | $__sp.Begin($pscmdlet) 19 | #Write-Host '[Leaving Begin Out-Default]' 20 | } 21 | 22 | process { 23 | #Write-Host '[Entering Process Out-Default]' 24 | if ($_ -is [System.Management.Automation.ErrorRecord]) { 25 | Write-Verbose -Message 'Error record:' 4>&1 | Out-Default 26 | Write-Verbose -Message (Remove-TrailingNewLine (Out-String -InputObject $_ -Width 2147483647)) 4>&1 | Out-Default 27 | Write-Verbose -Message 'Script stack trace:' 4>&1 | Out-Default 28 | Write-Verbose -Message "$($_.ScriptStackTrace)" 4>&1 | Out-Default 29 | Write-Verbose -Message 'Exception:' 4>&1 | Out-Default 30 | Write-Verbose -Message $_.Exception.ToString() 4>&1 | Out-Default 31 | Write-TaskError -Message $_.Exception.Message 32 | } elseif ($_ -is [System.Management.Automation.WarningRecord]) { 33 | Write-TaskWarning -Message (Remove-TrailingNewLine (Out-String -InputObject $_ -Width 2147483647)) 34 | } elseif ($_ -is [System.Management.Automation.VerboseRecord] -and !$global:__vstsNoOverrideVerbose) { 35 | foreach ($private:str in (Format-DebugMessage -Object $_)) { 36 | Write-TaskVerbose -Message $private:str 37 | } 38 | } elseif ($_ -is [System.Management.Automation.DebugRecord] -and !$global:__vstsNoOverrideVerbose) { 39 | foreach ($private:str in (Format-DebugMessage -Object $_)) { 40 | Write-TaskDebug -Message $private:str 41 | } 42 | } else { 43 | # TODO: Consider using out-string here to control the width. As a security precaution it would actually be best to set it to max so wrapping doesn't interfere with secret masking. 44 | $__sp.Process($_) 45 | } 46 | 47 | #Write-Host '[Leaving Process Out-Default]' 48 | } 49 | 50 | end { 51 | #Write-Host '[Entering End Out-Default]' 52 | $__sp.End() 53 | #Write-Host '[Leaving End Out-Default]' 54 | } 55 | } 56 | 57 | ######################################## 58 | # Private functions. 59 | ######################################## 60 | function Format-DebugMessage { 61 | [CmdletBinding()] 62 | param([psobject]$Object) 63 | 64 | $private:str = Out-String -InputObject $Object -Width 2147483647 65 | $private:str = Remove-TrailingNewLine $private:str 66 | "$private:str".Replace("`r`n", "`n").Replace("`r", "`n").Split("`n"[0]) 67 | } 68 | 69 | function Remove-TrailingNewLine { 70 | [CmdletBinding()] 71 | param($Str) 72 | if ([object]::ReferenceEquals($Str, $null)) { 73 | return $Str 74 | } elseif ($Str.EndsWith("`r`n")) { 75 | return $Str.Substring(0, $Str.Length - 2) 76 | } else { 77 | return $Str 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/PSGetModuleInfo.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/PSGetModuleInfo.xml -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/Strings/resources.resjson/de-de/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "Agentversion {0} oder höher ist erforderlich.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Der Containerpfad wurde nicht gefunden: \"{0}\".", 4 | "loc.messages.PSLIB_EndpointAuth0": "\"{0}\"-Dienstendpunkt-Anmeldeinformationen", 5 | "loc.messages.PSLIB_EndpointUrl0": "\"{0}\"-Dienstendpunkt-URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Fehler beim Aufzählen von Unterverzeichnissen für den folgenden Pfad: \"{0}\"", 7 | "loc.messages.PSLIB_FileNotFound0": "Die Datei wurde nicht gefunden: \"{0}\".", 8 | "loc.messages.PSLIB_Input0": "\"{0}\"-Eingabe", 9 | "loc.messages.PSLIB_InvalidPattern0": "Ungültiges Muster: \"{0}\"", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Der Blattpfad wurde nicht gefunden: \"{0}\".", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "Fehler bei der Normalisierung bzw. Erweiterung des Pfads. Die Pfadlänge wurde vom Kernel32-Subsystem nicht zurückgegeben für: \"{0}\"", 12 | "loc.messages.PSLIB_PathNotFound0": "Der Pfad wurde nicht gefunden: \"{0}\".", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Der Prozess \"{0}\" wurde mit dem Code \"{1}\" beendet.", 14 | "loc.messages.PSLIB_Required0": "Erforderlich: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Fehler beim Zeichenfolgenformat.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "Der Zeichenfolgen-Ressourcenschlüssel wurde nicht gefunden: \"{0}\".", 17 | "loc.messages.PSLIB_TaskVariable0": "\"{0}\"-Taskvariable" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/Strings/resources.resjson/en-US/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "Agent version {0} or higher is required.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Container path not found: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "'{0}' service endpoint credentials", 5 | "loc.messages.PSLIB_EndpointUrl0": "'{0}' service endpoint URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Enumerating subdirectories failed for path: '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "File not found: '{0}'", 8 | "loc.messages.PSLIB_Input0": "'{0}' input", 9 | "loc.messages.PSLIB_InvalidPattern0": "Invalid pattern: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Leaf path not found: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "Path normalization/expansion failed. The path length was not returned by the Kernel32 subsystem for: '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "Path not found: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Process '{0}' exited with code '{1}'.", 14 | "loc.messages.PSLIB_Required0": "Required: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "String format failed.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "String resource key not found: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "'{0}' task variable" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/Strings/resources.resjson/es-es/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "Se require la versión {0} o posterior del agente.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "No se encuentra la ruta de acceso del contenedor: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "Credenciales del punto de conexión de servicio '{0}'", 5 | "loc.messages.PSLIB_EndpointUrl0": "URL del punto de conexión de servicio '{0}'", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "No se pudieron enumerar los subdirectorios de la ruta de acceso: '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "Archivo no encontrado: '{0}'", 8 | "loc.messages.PSLIB_Input0": "Entrada '{0}'", 9 | "loc.messages.PSLIB_InvalidPattern0": "Patrón no válido: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "No se encuentra la ruta de acceso de la hoja: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "No se pudo normalizar o expandir la ruta de acceso. El subsistema Kernel32 no devolvió la longitud de la ruta de acceso para: '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "No se encuentra la ruta de acceso: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "El proceso '{0}' finalizó con el código '{1}'.", 14 | "loc.messages.PSLIB_Required0": "Se requiere: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Error de formato de cadena.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "No se encuentra la clave de recurso de la cadena: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "Variable de tarea '{0}'" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/Strings/resources.resjson/fr-fr/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "L'agent version {0} (ou une version ultérieure) est obligatoire.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Le chemin du conteneur est introuvable : '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "Informations d'identification du point de terminaison de service '{0}'", 5 | "loc.messages.PSLIB_EndpointUrl0": "URL du point de terminaison de service '{0}'", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Échec de l'énumération des sous-répertoires pour le chemin : '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "Fichier introuvable : {0}.", 8 | "loc.messages.PSLIB_Input0": "Entrée '{0}'", 9 | "loc.messages.PSLIB_InvalidPattern0": "Modèle non valide : '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Le chemin feuille est introuvable : '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "Échec de la normalisation/l'expansion du chemin. La longueur du chemin n'a pas été retournée par le sous-système Kernel32 pour : '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "Chemin introuvable : '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Le processus '{0}' s'est arrêté avec le code '{1}'.", 14 | "loc.messages.PSLIB_Required0": "Obligatoire : {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Échec du format de la chaîne.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "Clé de la ressource de type chaîne introuvable : '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "Variable de tâche '{0}'" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/Strings/resources.resjson/it-IT/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "È richiesta la versione dell'agente {0} o superiore.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Percorso del contenitore non trovato: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "Credenziali dell'endpoint servizio '{0}'", 5 | "loc.messages.PSLIB_EndpointUrl0": "URL dell'endpoint servizio '{0}'", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "L'enumerazione delle sottodirectory per il percorso '{0}' non è riuscita", 7 | "loc.messages.PSLIB_FileNotFound0": "File non trovato: '{0}'", 8 | "loc.messages.PSLIB_Input0": "Input di '{0}'", 9 | "loc.messages.PSLIB_InvalidPattern0": "Criterio non valido: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Percorso foglia non trovato: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "La normalizzazione o l'espansione del percorso non è riuscita. Il sottosistema Kernel32 non ha restituito la lunghezza del percorso per '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "Percorso non trovato: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Il processo '{0}' è stato terminato ed è stato restituito il codice '{1}'.", 14 | "loc.messages.PSLIB_Required0": "Obbligatorio: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Errore nel formato della stringa.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "La chiave della risorsa stringa non è stata trovata: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "Variabile dell'attività '{0}'" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/Strings/resources.resjson/ja-jp/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "バージョン {0} 以降のエージェントが必要です。", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "コンテナーのパスが見つかりません: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "'{0}' サービス エンドポイントの資格情報", 5 | "loc.messages.PSLIB_EndpointUrl0": "'{0}' サービス エンドポイントの URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "パス '{0}' のサブディレクトリを列挙できませんでした", 7 | "loc.messages.PSLIB_FileNotFound0": "ファイルが見つかりません: '{0}'", 8 | "loc.messages.PSLIB_Input0": "'{0}' 入力", 9 | "loc.messages.PSLIB_InvalidPattern0": "使用できないパターンです: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "リーフ パスが見つかりません: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "パスの正規化/展開に失敗しました。Kernel32 サブシステムからパス '{0}' の長さが返されませんでした", 12 | "loc.messages.PSLIB_PathNotFound0": "パスが見つかりません: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "プロセス '{0}' がコード '{1}' で終了しました。", 14 | "loc.messages.PSLIB_Required0": "必要: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "文字列のフォーマットに失敗しました。", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "文字列のリソース キーが見つかりません: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "'{0}' タスク変数" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/Strings/resources.resjson/ko-KR/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "에이전트 버전 {0} 이상이 필요합니다.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "컨테이너 경로를 찾을 수 없음: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "'{0}' 서비스 끝점 자격 증명", 5 | "loc.messages.PSLIB_EndpointUrl0": "'{0}' 서비스 끝점 URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "경로에 대해 하위 디렉터리를 열거하지 못함: '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "{0} 파일을 찾을 수 없습니다.", 8 | "loc.messages.PSLIB_Input0": "'{0}' 입력", 9 | "loc.messages.PSLIB_InvalidPattern0": "잘못된 패턴: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Leaf 경로를 찾을 수 없음: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "경로 정규화/확장에 실패했습니다. 다음에 대해 Kernel32 subsystem에서 경로 길이를 반환하지 않음: '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "경로를 찾을 수 없음: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "'{1}' 코드로 '{0}' 프로세스가 종료되었습니다.", 14 | "loc.messages.PSLIB_Required0": "필수: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "문자열을 포맷하지 못했습니다.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "문자열 리소스 키를 찾을 수 없음: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "'{0}' 작업 변수" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/Strings/resources.resjson/ru-RU/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "Требуется версия агента {0} или более поздняя.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Путь к контейнеру не найден: \"{0}\".", 4 | "loc.messages.PSLIB_EndpointAuth0": "Учетные данные конечной точки службы \"{0}\"", 5 | "loc.messages.PSLIB_EndpointUrl0": "URL-адрес конечной точки службы \"{0}\"", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Сбой перечисления подкаталогов для пути: \"{0}\".", 7 | "loc.messages.PSLIB_FileNotFound0": "Файл не найден: \"{0}\".", 8 | "loc.messages.PSLIB_Input0": "Входные данные \"{0}\".", 9 | "loc.messages.PSLIB_InvalidPattern0": "Недопустимый шаблон: \"{0}\".", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Путь к конечному объекту не найден: \"{0}\".", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "Сбой нормализации и расширения пути. Длина пути не была возвращена подсистемой Kernel32 для: \"{0}\".", 12 | "loc.messages.PSLIB_PathNotFound0": "Путь не найден: \"{0}\".", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Процесс \"{0}\" завершил работу с кодом \"{1}\".", 14 | "loc.messages.PSLIB_Required0": "Требуется: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Сбой формата строки.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "Ключ ресурса строки не найден: \"{0}\".", 17 | "loc.messages.PSLIB_TaskVariable0": "Переменная задачи \"{0}\"" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/Strings/resources.resjson/zh-CN/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "需要代理版本 {0} 或更高版本。", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "找不到容器路径:“{0}”", 4 | "loc.messages.PSLIB_EndpointAuth0": "“{0}”服务终结点凭据", 5 | "loc.messages.PSLIB_EndpointUrl0": "“{0}”服务终结点 URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "枚举路径的子目录失败:“{0}”", 7 | "loc.messages.PSLIB_FileNotFound0": "找不到文件: {0}。", 8 | "loc.messages.PSLIB_Input0": "“{0}”输入", 9 | "loc.messages.PSLIB_InvalidPattern0": "无效的模式:“{0}”", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "找不到叶路径:“{0}”", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "路径规范化/扩展失败。路径长度不是由“{0}”的 Kernel32 子系统返回的", 12 | "loc.messages.PSLIB_PathNotFound0": "找不到路径:“{0}”", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "过程“{0}”已退出,代码为“{1}”。", 14 | "loc.messages.PSLIB_Required0": "必需: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "字符串格式无效。", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "找不到字符串资源关键字:“{0}”", 17 | "loc.messages.PSLIB_TaskVariable0": "“{0}”任务变量" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/Strings/resources.resjson/zh-TW/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "需要代理程式版本 {0} 或更新的版本。", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "找不到容器路徑: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "'{0}' 服務端點認證", 5 | "loc.messages.PSLIB_EndpointUrl0": "'{0}' 服務端點 URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "為路徑列舉子目錄失敗: '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "找不到檔案: '{0}'", 8 | "loc.messages.PSLIB_Input0": "'{0}' 輸入", 9 | "loc.messages.PSLIB_InvalidPattern0": "模式無效: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "找不到分葉路徑: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "路徑正規化/展開失敗。Kernel32 子系統未傳回 '{0}' 的路徑長度", 12 | "loc.messages.PSLIB_PathNotFound0": "找不到路徑: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "處理序 '{0}' 以返回碼 '{1}' 結束。", 14 | "loc.messages.PSLIB_Required0": "必要項: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "字串格式失敗。", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "找不到字串資源索引鍵: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "'{0}' 工作變數" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/ToolFunctions.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Asserts the agent version is at least the specified minimum. 4 | 5 | .PARAMETER Minimum 6 | Minimum version - must be 2.104.1 or higher. 7 | #> 8 | function Assert-Agent { 9 | [CmdletBinding()] 10 | param( 11 | [Parameter(Mandatory = $true)] 12 | [version]$Minimum) 13 | 14 | if (([version]'2.104.1').CompareTo($Minimum) -ge 1) { 15 | Write-Error "Assert-Agent requires the parameter to be 2.104.1 or higher." 16 | return 17 | } 18 | 19 | $agent = Get-TaskVariable -Name 'agent.version' 20 | if (!$agent -or $Minimum.CompareTo([version]$agent) -ge 1) { 21 | Write-Error (Get-LocString -Key 'PSLIB_AgentVersion0Required' -ArgumentList $Minimum) 22 | } 23 | } 24 | 25 | <# 26 | .SYNOPSIS 27 | Asserts that a path exists. Throws if the path does not exist. 28 | 29 | .PARAMETER PassThru 30 | True to return the path. 31 | #> 32 | function Assert-Path { 33 | [CmdletBinding()] 34 | param( 35 | [Parameter(Mandatory = $true)] 36 | [string]$LiteralPath, 37 | [Microsoft.PowerShell.Commands.TestPathType]$PathType = [Microsoft.PowerShell.Commands.TestPathType]::Any, 38 | [switch]$PassThru) 39 | 40 | if ($PathType -eq [Microsoft.PowerShell.Commands.TestPathType]::Any) { 41 | Write-Verbose "Asserting path exists: '$LiteralPath'" 42 | } else { 43 | Write-Verbose "Asserting $("$PathType".ToLowerInvariant()) path exists: '$LiteralPath'" 44 | } 45 | 46 | if (Test-Path -LiteralPath $LiteralPath -PathType $PathType) { 47 | if ($PassThru) { 48 | return $LiteralPath 49 | } 50 | 51 | return 52 | } 53 | 54 | $resourceKey = switch ($PathType) { 55 | ([Microsoft.PowerShell.Commands.TestPathType]::Container) { "PSLIB_ContainerPathNotFound0" ; break } 56 | ([Microsoft.PowerShell.Commands.TestPathType]::Leaf) { "PSLIB_LeafPathNotFound0" ; break } 57 | default { "PSLIB_PathNotFound0" } 58 | } 59 | 60 | throw (Get-LocString -Key $resourceKey -ArgumentList $LiteralPath) 61 | } 62 | 63 | <# 64 | .SYNOPSIS 65 | Executes an external program. 66 | 67 | .DESCRIPTION 68 | Executes an external program and waits for the process to exit. 69 | 70 | After calling this command, the exit code of the process can be retrieved from the variable $LASTEXITCODE. 71 | 72 | .PARAMETER Encoding 73 | This parameter not required for most scenarios. Indicates how to interpret the encoding from the external program. An example use case would be if an external program outputs UTF-16 XML and the output needs to be parsed. 74 | 75 | .PARAMETER RequireExitCodeZero 76 | Indicates whether to write an error to the error pipeline if the exit code is not zero. 77 | #> 78 | function Invoke-Tool { # TODO: RENAME TO INVOKE-PROCESS? 79 | [CmdletBinding()] 80 | param( 81 | [ValidatePattern('^[^\r\n]*$')] 82 | [Parameter(Mandatory = $true)] 83 | [string]$FileName, 84 | [ValidatePattern('^[^\r\n]*$')] 85 | [Parameter()] 86 | [string]$Arguments, 87 | [string]$WorkingDirectory, 88 | [System.Text.Encoding]$Encoding, 89 | [switch]$RequireExitCodeZero) 90 | 91 | Trace-EnteringInvocation $MyInvocation 92 | $isPushed = $false 93 | $originalEncoding = $null 94 | try { 95 | if ($Encoding) { 96 | $originalEncoding = [System.Console]::OutputEncoding 97 | [System.Console]::OutputEncoding = $Encoding 98 | } 99 | 100 | if ($WorkingDirectory) { 101 | Push-Location -LiteralPath $WorkingDirectory -ErrorAction Stop 102 | $isPushed = $true 103 | } 104 | 105 | $FileName = $FileName.Replace('"', '').Replace("'", "''") 106 | Write-Host "##[command]""$FileName"" $Arguments" 107 | Invoke-Expression "& '$FileName' --% $Arguments" 108 | Write-Verbose "Exit code: $LASTEXITCODE" 109 | if ($RequireExitCodeZero -and $LASTEXITCODE -ne 0) { 110 | Write-Error (Get-LocString -Key PSLIB_Process0ExitedWithCode1 -ArgumentList ([System.IO.Path]::GetFileName($FileName)), $LASTEXITCODE) 111 | } 112 | } finally { 113 | if ($originalEncoding) { 114 | [System.Console]::OutputEncoding = $originalEncoding 115 | } 116 | 117 | if ($isPushed) { 118 | Pop-Location 119 | } 120 | 121 | Trace-LeavingInvocation $MyInvocation 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/TraceFunctions.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Writes verbose information about the invocation being entered. 4 | 5 | .DESCRIPTION 6 | Used to trace verbose information when entering a function/script. Writes an entering message followed by a short description of the invocation. Additionally each bound parameter and unbound argument is also traced. 7 | 8 | .PARAMETER Parameter 9 | Wildcard pattern to control which bound parameters are traced. 10 | #> 11 | function Trace-EnteringInvocation { 12 | [CmdletBinding()] 13 | param( 14 | [Parameter(Mandatory = $true)] 15 | [System.Management.Automation.InvocationInfo]$InvocationInfo, 16 | [string[]]$Parameter = '*') 17 | 18 | Write-Verbose "Entering $(Get-InvocationDescription $InvocationInfo)." 19 | $OFS = ", " 20 | if ($InvocationInfo.BoundParameters.Count -and $Parameter.Count) { 21 | if ($Parameter.Count -eq 1 -and $Parameter[0] -eq '*') { 22 | # Trace all parameters. 23 | foreach ($key in $InvocationInfo.BoundParameters.Keys) { 24 | Write-Verbose " $($key): '$($InvocationInfo.BoundParameters[$key])'" 25 | } 26 | } else { 27 | # Trace matching parameters. 28 | foreach ($key in $InvocationInfo.BoundParameters.Keys) { 29 | foreach ($p in $Parameter) { 30 | if ($key -like $p) { 31 | Write-Verbose " $($key): '$($InvocationInfo.BoundParameters[$key])'" 32 | break 33 | } 34 | } 35 | } 36 | } 37 | } 38 | 39 | # Trace all unbound arguments. 40 | if (@($InvocationInfo.UnboundArguments).Count) { 41 | for ($i = 0 ; $i -lt $InvocationInfo.UnboundArguments.Count ; $i++) { 42 | Write-Verbose " args[$i]: '$($InvocationInfo.UnboundArguments[$i])'" 43 | } 44 | } 45 | } 46 | 47 | <# 48 | .SYNOPSIS 49 | Writes verbose information about the invocation being left. 50 | 51 | .DESCRIPTION 52 | Used to trace verbose information when leaving a function/script. Writes a leaving message followed by a short description of the invocation. 53 | #> 54 | function Trace-LeavingInvocation { 55 | [CmdletBinding()] 56 | param( 57 | [Parameter(Mandatory = $true)] 58 | [System.Management.Automation.InvocationInfo]$InvocationInfo) 59 | 60 | Write-Verbose "Leaving $(Get-InvocationDescription $InvocationInfo)." 61 | } 62 | 63 | <# 64 | .SYNOPSIS 65 | Writes verbose information about paths. 66 | 67 | .DESCRIPTION 68 | Writes verbose information about the paths. The paths are sorted and a the common root is written only once, followed by each relative path. 69 | 70 | .PARAMETER PassThru 71 | Indicates whether to return the sorted paths. 72 | #> 73 | function Trace-Path { 74 | [CmdletBinding()] 75 | param( 76 | [string[]]$Path, 77 | [switch]$PassThru) 78 | 79 | if ($Path.Count -eq 0) { 80 | Write-Verbose "No paths." 81 | if ($PassThru) { 82 | $Path 83 | } 84 | } elseif ($Path.Count -eq 1) { 85 | Write-Verbose "Path: $($Path[0])" 86 | if ($PassThru) { 87 | $Path 88 | } 89 | } else { 90 | # Find the greatest common root. 91 | $sorted = $Path | Sort-Object 92 | $firstPath = $sorted[0].ToCharArray() 93 | $lastPath = $sorted[-1].ToCharArray() 94 | $commonEndIndex = 0 95 | $j = if ($firstPath.Length -lt $lastPath.Length) { $firstPath.Length } else { $lastPath.Length } 96 | for ($i = 0 ; $i -lt $j ; $i++) { 97 | if ($firstPath[$i] -eq $lastPath[$i]) { 98 | if ($firstPath[$i] -eq '\') { 99 | $commonEndIndex = $i 100 | } 101 | } else { 102 | break 103 | } 104 | } 105 | 106 | if ($commonEndIndex -eq 0) { 107 | # No common root. 108 | Write-Verbose "Paths:" 109 | foreach ($p in $sorted) { 110 | Write-Verbose " $p" 111 | } 112 | } else { 113 | Write-Verbose "Paths: $($Path[0].Substring(0, $commonEndIndex + 1))" 114 | foreach ($p in $sorted) { 115 | Write-Verbose " $($p.Substring($commonEndIndex + 1))" 116 | } 117 | } 118 | 119 | if ($PassThru) { 120 | $sorted 121 | } 122 | } 123 | } 124 | 125 | ######################################## 126 | # Private functions. 127 | ######################################## 128 | function Get-InvocationDescription { 129 | [CmdletBinding()] 130 | param([System.Management.Automation.InvocationInfo]$InvocationInfo) 131 | 132 | if ($InvocationInfo.MyCommand.Path) { 133 | $InvocationInfo.MyCommand.Path 134 | } elseif ($InvocationInfo.MyCommand.Name) { 135 | $InvocationInfo.MyCommand.Name 136 | } else { 137 | $InvocationInfo.MyCommand.CommandType 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/VstsTaskSdk.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/VstsTaskSdk.dll -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/VstsTaskSdk.psd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/VstsTaskSdk.psd1 -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/VstsTaskSdk.psm1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | [ValidateNotNull()] 4 | [Parameter()] 5 | [hashtable]$ModuleParameters = @{ }) 6 | 7 | if ($host.Name -ne 'ConsoleHost') { 8 | Write-Warning "VstsTaskSdk is designed for use with powershell.exe (ConsoleHost). Output may be different when used with other hosts." 9 | } 10 | 11 | # Private module variables. 12 | [bool]$script:nonInteractive = "$($ModuleParameters['NonInteractive'])" -eq 'true' 13 | Write-Verbose "NonInteractive: $script:nonInteractive" 14 | 15 | # VstsTaskSdk.dll contains the TerminationException and NativeMethods for handle long path 16 | # We used to do inline C# in this powershell module 17 | # However when csc compile the inline C#, it will hit process env block size limit since it's not use unicode to encode env 18 | # To solve the env block size problem, we choose to put all inline C# into an assembly VstsTaskSdk.dll, signing it, package with the PS modules. 19 | Write-Verbose "Loading compiled helper $PSScriptRoot\VstsTaskSdk.dll." 20 | Add-Type -LiteralPath $PSScriptRoot\VstsTaskSdk.dll 21 | 22 | # Import/export functions. 23 | . "$PSScriptRoot\FindFunctions.ps1" 24 | . "$PSScriptRoot\InputFunctions.ps1" 25 | . "$PSScriptRoot\LegacyFindFunctions.ps1" 26 | . "$PSScriptRoot\LocalizationFunctions.ps1" 27 | . "$PSScriptRoot\LoggingCommandFunctions.ps1" 28 | . "$PSScriptRoot\LongPathFunctions.ps1" 29 | . "$PSScriptRoot\ServerOMFunctions.ps1" 30 | . "$PSScriptRoot\ToolFunctions.ps1" 31 | . "$PSScriptRoot\TraceFunctions.ps1" 32 | . "$PSScriptRoot\OutFunctions.ps1" # Load the out functions after all of the other functions are loaded. 33 | Export-ModuleMember -Function @( 34 | # Find functions. 35 | 'Find-Match' 36 | 'New-FindOptions' 37 | 'New-MatchOptions' 38 | 'Select-Match' 39 | # Input functions. 40 | 'Get-Endpoint' 41 | 'Get-SecureFileTicket' 42 | 'Get-SecureFileName' 43 | 'Get-Input' 44 | 'Get-TaskVariable' 45 | 'Get-TaskVariableInfo' 46 | 'Set-TaskVariable' 47 | # Legacy find functions. 48 | 'Find-Files' 49 | # Localization functions. 50 | 'Get-LocString' 51 | 'Import-LocStrings' 52 | # Logging command functions. 53 | 'Write-AddAttachment' 54 | 'Write-AddBuildTag' 55 | 'Write-AssociateArtifact' 56 | 'Write-LogDetail' 57 | 'Write-PrependPath' 58 | 'Write-SetEndpoint' 59 | 'Write-SetProgress' 60 | 'Write-SetResult' 61 | 'Write-SetSecret' 62 | 'Write-SetVariable' 63 | 'Write-TaskDebug' 64 | 'Write-TaskError' 65 | 'Write-TaskVerbose' 66 | 'Write-TaskWarning' 67 | 'Write-UpdateBuildNumber' 68 | 'Write-UpdateReleaseName' 69 | 'Write-UploadArtifact' 70 | 'Write-UploadBuildLog' 71 | 'Write-UploadFile' 72 | 'Write-UploadSummary' 73 | # Out functions. 74 | 'Out-Default' 75 | # Server OM functions. 76 | 'Get-AssemblyReference' 77 | 'Get-TfsClientCredentials' 78 | 'Get-TfsService' 79 | 'Get-VssCredentials' 80 | 'Get-VssHttpClient' 81 | # Tool functions. 82 | 'Assert-Agent' 83 | 'Assert-Path' 84 | 'Invoke-Tool' 85 | # Trace functions. 86 | 'Trace-EnteringInvocation' 87 | 'Trace-LeavingInvocation' 88 | 'Trace-Path' 89 | # Proxy functions 90 | 'Get-WebProxy' 91 | # Client cert functions 92 | 'Get-ClientCertificate' 93 | ) 94 | 95 | # Override Out-Default globally. 96 | $null = New-Item -Force -Path "function:\global:Out-Default" -Value (Get-Command -CommandType Function -Name Out-Default -ListImported) 97 | New-Alias -Name Out-Default -Value "global:Out-Default" -Scope global 98 | 99 | # Perform some initialization in a script block to enable merging the pipelines. 100 | $scriptText = @" 101 | # Load the SDK resource strings. 102 | Import-LocStrings "$PSScriptRoot\lib.json" 103 | 104 | # Load the module that contains ConvertTo-SecureString. 105 | if (!(Get-Module -Name Microsoft.PowerShell.Security)) { 106 | Write-Verbose "Importing the module 'Microsoft.PowerShell.Security'." 107 | Import-Module -Name Microsoft.PowerShell.Security 2>&1 | 108 | ForEach-Object { 109 | if (`$_ -is [System.Management.Automation.ErrorRecord]) { 110 | Write-Verbose `$_.Exception.Message 111 | } else { 112 | ,`$_ 113 | } 114 | } 115 | } 116 | "@ 117 | . ([scriptblock]::Create($scriptText)) 2>&1 3>&1 4>&1 5>&1 | Out-Default 118 | 119 | # Create Invoke-VstsTaskScript in a special way so it is not bound to the module. 120 | # Otherwise calling the task script block would run within the module context. 121 | # 122 | # An alternative way to solve the problem is to close the script block (i.e. closure). 123 | # However, that introduces a different problem. Closed script blocks are created within 124 | # a dynamic module. Each module gets it's own session state separate from the global 125 | # session state. When running in a regular script context, Import-Module calls import 126 | # the target module into the global session state. When running in a module context, 127 | # Import-Module calls import the target module into the caller module's session state. 128 | # 129 | # The goal of a task may include executing ad-hoc scripts. Therefore, task scripts 130 | # should run in regular script context. The end user specifying an ad-hoc script expects 131 | # the module import rules to be consistent with the default behavior (i.e. imported 132 | # into the global session state). 133 | $null = New-Item -Force -Path "function:\global:Invoke-VstsTaskScript" -Value ([scriptblock]::Create(@' 134 | [CmdletBinding()] 135 | param( 136 | [Parameter(Mandatory = $true)] 137 | [scriptblock]$ScriptBlock) 138 | 139 | try { 140 | $global:ErrorActionPreference = 'Stop' 141 | 142 | # Initialize the environment. 143 | $vstsModule = Get-Module -Name VstsTaskSdk 144 | Write-Verbose "$($vstsModule.Name) $($vstsModule.Version) commit $($vstsModule.PrivateData.PSData.CommitHash)" 4>&1 | Out-Default 145 | & $vstsModule Initialize-Inputs 4>&1 | Out-Default 146 | 147 | # Remove the local variable before calling the user's script. 148 | Remove-Variable -Name vstsModule 149 | 150 | # Call the user's script. 151 | $ScriptBlock | 152 | ForEach-Object { 153 | # Remove the scriptblock variable before calling it. 154 | Remove-Variable -Name ScriptBlock 155 | & $_ 2>&1 3>&1 4>&1 5>&1 | Out-Default 156 | } 157 | } catch [VstsTaskSdk.TerminationException] { 158 | # Special internal exception type to control the flow. Not currently intended 159 | # for public usage and subject to change. 160 | $global:__vstsNoOverrideVerbose = '' 161 | Write-Verbose "Task script terminated." 4>&1 | Out-Default 162 | } catch { 163 | $global:__vstsNoOverrideVerbose = '' 164 | Write-Verbose "Caught exception from task script." 4>&1 | Out-Default 165 | $_ | Out-Default 166 | Write-Host "##vso[task.complete result=Failed]" 167 | } 168 | '@)) 169 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/ps_modules/VstsTaskSdk/lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "messages": { 3 | "PSLIB_AgentVersion0Required": "Agent version {0} or higher is required.", 4 | "PSLIB_ContainerPathNotFound0": "Container path not found: '{0}'", 5 | "PSLIB_EndpointAuth0": "'{0}' service endpoint credentials", 6 | "PSLIB_EndpointUrl0": "'{0}' service endpoint URL", 7 | "PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Enumerating subdirectories failed for path: '{0}'", 8 | "PSLIB_FileNotFound0": "File not found: '{0}'", 9 | "PSLIB_Input0": "'{0}' input", 10 | "PSLIB_InvalidPattern0": "Invalid pattern: '{0}'", 11 | "PSLIB_LeafPathNotFound0": "Leaf path not found: '{0}'", 12 | "PSLIB_PathLengthNotReturnedFor0": "Path normalization/expansion failed. The path length was not returned by the Kernel32 subsystem for: '{0}'", 13 | "PSLIB_PathNotFound0": "Path not found: '{0}'", 14 | "PSLIB_Process0ExitedWithCode1": "Process '{0}' exited with code '{1}'.", 15 | "PSLIB_Required0": "Required: {0}", 16 | "PSLIB_StringFormatFailed": "String format failed.", 17 | "PSLIB_StringResourceKeyNotFound0": "String resource key not found: '{0}'", 18 | "PSLIB_TaskVariable0": "'{0}' task variable" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV3/task.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "7dad075d-a817-45ac-baab-4c1376d2885e", 3 | "name": "WindowsServiceManager", 4 | "friendlyName": "Windows Service Manager", 5 | "description": "Deploys a Windows Service to an Agent or a Deployment Group Target using WinRM.", 6 | "helpMarkDown": "[More Information](https://github.com/Dejulia489/WindowsServiceManager)", 7 | "category": "Utility", 8 | "visibility": [ 9 | "Build", 10 | "Release" 11 | ], 12 | "author": "MDSolutions", 13 | "version": { 14 | "Major": 3, 15 | "Minor": 6, 16 | "Patch": 0 17 | }, 18 | "instanceNameFormat": "Deploy Windows Service", 19 | "groups": [ 20 | { 21 | "name": "advanced", 22 | "displayName": "Advanced", 23 | "isExpanded": true 24 | }, 25 | { 26 | "name": "installation", 27 | "displayName": "Install Service", 28 | "isExpanded": true 29 | } 30 | ], 31 | "inputs": [ 32 | { 33 | "name": "DeploymentType", 34 | "type": "radio", 35 | "label": "Deployment Type", 36 | "required": true, 37 | "defaultValue": "Agent", 38 | "helpMarkDown": "Deploy with an Agent or a Deployment Group.", 39 | "options": { 40 | "Agent": "Agent", 41 | "DeploymentGroup": "Deployment Group" 42 | } 43 | }, 44 | { 45 | "name": "Machines", 46 | "label": "Machines", 47 | "required": true, 48 | "helpMarkDown": "Provide a comma separated list of machine IP addresses or FQDNs. Or provide output variable of other tasks. Eg: $(variableName).", 49 | "visibleRule": "DeploymentType=Agent" 50 | }, 51 | { 52 | "name": "AdminLogin", 53 | "label": "Admin Login", 54 | "required": true, 55 | "helpMarkDown": "Administrator login for the target machines.", 56 | "visibleRule": "DeploymentType=Agent" 57 | }, 58 | { 59 | "name": "Password", 60 | "label": "Password", 61 | "required": true, 62 | "helpMarkDown": "Password for administrator login for the target machines. It can accept variable defined in Build/Release definitions as '$(passwordVariable)'. You may mark variable type as 'secret' to secure it.", 63 | "visibleRule": "DeploymentType=Agent" 64 | }, 65 | { 66 | "name": "ServiceName", 67 | "type": "string", 68 | "label": "Service Name", 69 | "defaultValue": "", 70 | "required": true, 71 | "helpMarkDown": "The exact name of the windows service installed on the deployment group target." 72 | }, 73 | { 74 | "name": "ArtifactPath", 75 | "type": "filePath", 76 | "label": "Artifact Path", 77 | "defaultValue": "", 78 | "required": true, 79 | "helpMarkDown": "The path to the windows service artifact." 80 | }, 81 | { 82 | "name": "TimeOut", 83 | "type": "string", 84 | "label": "Timeout", 85 | "defaultValue": "30", 86 | "required": true, 87 | "helpMarkDown": "The number of seconds to wait for the service to stop." 88 | }, 89 | { 90 | "name": "StopProcess", 91 | "type": "boolean", 92 | "label": "Stop Process", 93 | "defaultValue": false, 94 | "groupName": "advanced", 95 | "helpMarkDown": "Stops the process if the service does not respond within the timeout limit." 96 | }, 97 | { 98 | "name": "CleanInstall", 99 | "type": "boolean", 100 | "label": "Clean Install", 101 | "defaultValue": false, 102 | "groupName": "advanced", 103 | "helpMarkDown": "Deletes all files from the Windows Service parent directory prior to deployment of the artifact." 104 | }, 105 | { 106 | "name": "InstallService", 107 | "type": "boolean", 108 | "label": "Install the windows service", 109 | "required": false, 110 | "groupName": "installation", 111 | "defaultValue": "false", 112 | "helpMarkDown": "Select the option to install the windows service." 113 | }, 114 | { 115 | "name": "InstallationPath", 116 | "type": "string", 117 | "label": "Installation Path", 118 | "defaultValue": "", 119 | "required": true, 120 | "groupName": "installation", 121 | "visibleRule": "InstallService=true", 122 | "helpMarkDown": "Provide the path to the executable file." 123 | }, 124 | { 125 | "name": "RunAsUsername", 126 | "type": "string", 127 | "label": "Run As Username", 128 | "defaultValue": "", 129 | "required": false, 130 | "groupName": "installation", 131 | "visibleRule": "InstallService=true", 132 | "helpMarkDown": "Provide the username the service should run as." 133 | }, 134 | { 135 | "name": "RunAsPassword", 136 | "type": "string", 137 | "label": "Run As Password", 138 | "defaultValue": "", 139 | "required": false, 140 | "groupName": "installation", 141 | "visibleRule": "InstallService=true", 142 | "helpMarkDown": "Provide the password for the Run As Username. It can accept variable defined in Build/Release definitions as '$(passwordVariable)'. You may mark variable type as 'secret' to secure it." 143 | } 144 | ], 145 | "execution": { 146 | "PowerShell3": { 147 | "target": "DeployWindowsService.ps1", 148 | "workingDirectory": "$(currentDirectory)" 149 | } 150 | } 151 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/Add-LocalUserToLogonAsAService.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | This cmdlet gives a user privileges to LogonAsAService. 4 | .DESCRIPTION 5 | This cmdlet gives a user privileges to LogonAsAService. 6 | .PARAMETER User 7 | The user name of the local user 8 | .EXAMPLE 9 | Add-LocalUserToLogonAsAService -user $UserName 10 | #> 11 | 12 | #written by Ingo Karstein, http://blog.karstein-consulting.com, # v1.0, 01/03/2014 13 | #function added by Robin Carlsson, robintheswede.com, 2017-03-08 14 | 15 | function Add-LocalUserToLogonAsAService { 16 | [CmdletBinding()] 17 | param ( 18 | [parameter(Mandatory = $true)] 19 | [string]$user 20 | ) 21 | 22 | PROCESS { 23 | if ( [string]::IsNullOrEmpty($user) ) { 24 | return Write-Error "no account specified" 25 | } 26 | 27 | $sidstr = $null 28 | try { 29 | $ntprincipal = new-object System.Security.Principal.NTAccount "$user" 30 | $sid = $ntprincipal.Translate([System.Security.Principal.SecurityIdentifier]) 31 | $sidstr = $sid.Value.ToString() 32 | } 33 | catch { 34 | $sidstr = $null 35 | } 36 | 37 | Write-Host "Account: $($user)" -ForegroundColor DarkCyan 38 | 39 | if ( [string]::IsNullOrEmpty($sidstr) ) { 40 | return Write-Error "Account not found!" 41 | } 42 | 43 | Write-Host "Account SID: $($sidstr)" -ForegroundColor DarkCyan 44 | 45 | $tmp = [System.IO.Path]::GetTempFileName() 46 | 47 | Write-Host "Export current Local Security Policy" -ForegroundColor DarkCyan 48 | secedit.exe /export /cfg "$($tmp)" 49 | 50 | $c = Get-Content -Path $tmp 51 | 52 | $currentSetting = "" 53 | 54 | foreach ($s in $c) { 55 | if ( $s -like "SeServiceLogonRight*") { 56 | $x = $s.split("=", [System.StringSplitOptions]::RemoveEmptyEntries) 57 | $currentSetting = $x[1].Trim() 58 | } 59 | } 60 | 61 | if ( $currentSetting -notlike "*$($sidstr)*" ) { 62 | Write-Host "Modify Setting ""Logon as a Service""" -ForegroundColor DarkCyan 63 | 64 | if ( [string]::IsNullOrEmpty($currentSetting) ) { 65 | $currentSetting = "*$($sidstr)" 66 | } 67 | else { 68 | $currentSetting = "*$($sidstr),$($currentSetting)" 69 | } 70 | 71 | Write-Host "$currentSetting" 72 | 73 | $outfile = @" 74 | [Unicode] 75 | Unicode=yes 76 | [Version] 77 | signature="`$CHICAGO`$" 78 | Revision=1 79 | [Privilege Rights] 80 | SeServiceLogonRight = $($currentSetting) 81 | "@ 82 | 83 | $tmp2 = [System.IO.Path]::GetTempFileName() 84 | 85 | 86 | Write-Host "Import new settings to Local Security Policy" -ForegroundColor DarkCyan 87 | $outfile | Set-Content -Path $tmp2 -Encoding Unicode -Force 88 | 89 | #notepad.exe $tmp2 90 | Push-Location (Split-Path $tmp2) 91 | 92 | try { 93 | secedit.exe /configure /db "secedit.sdb" /cfg "$($tmp2)" /areas USER_RIGHTS 94 | #write-host "secedit.exe /configure /db ""secedit.sdb"" /cfg ""$($tmp2)"" /areas USER_RIGHTS " 95 | } 96 | finally { 97 | Pop-Location 98 | } 99 | } 100 | else { 101 | Write-Host "NO ACTIONS REQUIRED! Account already in ""Logon as a Service""" -ForegroundColor DarkCyan 102 | } 103 | 104 | Write-Host "Done." -ForegroundColor DarkCyan 105 | } 106 | } 107 | #Export-ModuleMember -Function Add-LocalUserToLogonAsAService -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV4/icon.png -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/LocalizationFunctions.ps1: -------------------------------------------------------------------------------- 1 | $script:resourceStrings = @{ } 2 | 3 | <# 4 | .SYNOPSIS 5 | Gets a localized resource string. 6 | 7 | .DESCRIPTION 8 | Gets a localized resource string and optionally formats the string with arguments. 9 | 10 | If the format fails (due to a bad format string or incorrect expected arguments in the format string), then the format string is returned followed by each of the arguments (delimited by a space). 11 | 12 | If the lookup key is not found, then the lookup key is returned followed by each of the arguments (delimited by a space). 13 | 14 | .PARAMETER Require 15 | Writes an error to the error pipeline if the endpoint is not found. 16 | #> 17 | function Get-LocString { 18 | [CmdletBinding()] 19 | param( 20 | [Parameter(Mandatory = $true, Position = 1)] 21 | [string]$Key, 22 | [Parameter(Position = 2)] 23 | [object[]]$ArgumentList = @( )) 24 | 25 | # Due to the dynamically typed nature of PowerShell, a single null argument passed 26 | # to an array parameter is interpreted as a null array. 27 | if ([object]::ReferenceEquals($null, $ArgumentList)) { 28 | $ArgumentList = @( $null ) 29 | } 30 | 31 | # Lookup the format string. 32 | $format = '' 33 | if (!($format = $script:resourceStrings[$Key])) { 34 | # Warn the key was not found. Prevent recursion if the lookup key is the 35 | # "string resource key not found" lookup key. 36 | $resourceNotFoundKey = 'PSLIB_StringResourceKeyNotFound0' 37 | if ($key -ne $resourceNotFoundKey) { 38 | Write-Warning (Get-LocString -Key $resourceNotFoundKey -ArgumentList $Key) 39 | } 40 | 41 | # Fallback to just the key itself if there aren't any arguments to format. 42 | if (!$ArgumentList.Count) { return $key } 43 | 44 | # Otherwise fallback to the key followed by the arguments. 45 | $OFS = " " 46 | return "$key $ArgumentList" 47 | } 48 | 49 | # Return the string if there aren't any arguments to format. 50 | if (!$ArgumentList.Count) { return $format } 51 | 52 | try { 53 | [string]::Format($format, $ArgumentList) 54 | } catch { 55 | Write-Warning (Get-LocString -Key 'PSLIB_StringFormatFailed') 56 | $OFS = " " 57 | "$format $ArgumentList" 58 | } 59 | } 60 | 61 | <# 62 | .SYNOPSIS 63 | Imports resource strings for use with Get-VstsLocString. 64 | 65 | .DESCRIPTION 66 | Imports resource strings for use with Get-VstsLocString. The imported strings are stored in an internal resource string dictionary. Optionally, if a separate resource file for the current culture exists, then the localized strings from that file then imported (overlaid) into the same internal resource string dictionary. 67 | 68 | Resource strings from the SDK are prefixed with "PSLIB_". This prefix should be avoided for custom resource strings. 69 | 70 | .Parameter LiteralPath 71 | JSON file containing resource strings. 72 | 73 | .EXAMPLE 74 | Import-VstsLocStrings -LiteralPath $PSScriptRoot\Task.json 75 | 76 | Imports strings from messages section in the JSON file. If a messages section is not defined, then no strings are imported. Example messages section: 77 | { 78 | "messages": { 79 | "Hello": "Hello you!", 80 | "Hello0": "Hello {0}!" 81 | } 82 | } 83 | 84 | .EXAMPLE 85 | Import-VstsLocStrings -LiteralPath $PSScriptRoot\Task.json 86 | 87 | Overlays strings from an optional separate resource file for the current culture. 88 | 89 | Given the task variable System.Culture is set to 'de-DE'. This variable is set by the agent based on the current culture for the job. 90 | Given the file Task.json contains: 91 | { 92 | "messages": { 93 | "GoodDay": "Good day!", 94 | } 95 | } 96 | Given the file resources.resjson\de-DE\resources.resjson: 97 | { 98 | "loc.messages.GoodDay": "Guten Tag!" 99 | } 100 | 101 | The net result from the import command would be one new key-value pair added to the internal dictionary: Key = 'GoodDay', Value = 'Guten Tag!' 102 | #> 103 | function Import-LocStrings { 104 | [CmdletBinding()] 105 | param( 106 | [Parameter(Mandatory = $true)] 107 | [string]$LiteralPath) 108 | 109 | # Validate the file exists. 110 | if (!(Test-Path -LiteralPath $LiteralPath -PathType Leaf)) { 111 | Write-Warning (Get-LocString -Key PSLIB_FileNotFound0 -ArgumentList $LiteralPath) 112 | return 113 | } 114 | 115 | # Load the json. 116 | Write-Verbose "Loading resource strings from: $LiteralPath" 117 | $count = 0 118 | if ($messages = (Get-Content -LiteralPath $LiteralPath -Encoding UTF8 | Out-String | ConvertFrom-Json).messages) { 119 | # Add each resource string to the hashtable. 120 | foreach ($member in (Get-Member -InputObject $messages -MemberType NoteProperty)) { 121 | [string]$key = $member.Name 122 | $script:resourceStrings[$key] = $messages."$key" 123 | $count++ 124 | } 125 | } 126 | 127 | Write-Verbose "Loaded $count strings." 128 | 129 | # Get the culture. 130 | $culture = Get-TaskVariable -Name "System.Culture" -Default "en-US" 131 | 132 | # Load the resjson. 133 | $resjsonPath = "$([System.IO.Path]::GetDirectoryName($LiteralPath))\Strings\resources.resjson\$culture\resources.resjson" 134 | if (Test-Path -LiteralPath $resjsonPath) { 135 | Write-Verbose "Loading resource strings from: $resjsonPath" 136 | $count = 0 137 | $resjson = Get-Content -LiteralPath $resjsonPath -Encoding UTF8 | Out-String | ConvertFrom-Json 138 | foreach ($member in (Get-Member -Name loc.messages.* -InputObject $resjson -MemberType NoteProperty)) { 139 | if (!($value = $resjson."$($member.Name)")) { 140 | continue 141 | } 142 | 143 | [string]$key = $member.Name.Substring('loc.messages.'.Length) 144 | $script:resourceStrings[$key] = $value 145 | $count++ 146 | } 147 | 148 | Write-Verbose "Loaded $count strings." 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/Minimatch.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/Minimatch.dll -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/OutFunctions.ps1: -------------------------------------------------------------------------------- 1 | # TODO: It would be better if the Out-Default function resolved the underlying Out-Default 2 | # command in the begin block. This would allow for supporting other modules that override 3 | # Out-Default. 4 | $script:outDefaultCmdlet = $ExecutionContext.InvokeCommand.GetCmdlet("Microsoft.PowerShell.Core\Out-Default") 5 | 6 | ######################################## 7 | # Public functions. 8 | ######################################## 9 | function Out-Default { 10 | [CmdletBinding(ConfirmImpact = "Medium")] 11 | param( 12 | [Parameter(ValueFromPipeline = $true)] 13 | [System.Management.Automation.PSObject]$InputObject) 14 | 15 | begin { 16 | #Write-Host '[Entering Begin Out-Default]' 17 | $__sp = { & $script:outDefaultCmdlet @PSBoundParameters }.GetSteppablePipeline() 18 | $__sp.Begin($pscmdlet) 19 | #Write-Host '[Leaving Begin Out-Default]' 20 | } 21 | 22 | process { 23 | #Write-Host '[Entering Process Out-Default]' 24 | if ($_ -is [System.Management.Automation.ErrorRecord]) { 25 | Write-Verbose -Message 'Error record:' 4>&1 | Out-Default 26 | Write-Verbose -Message (Remove-TrailingNewLine (Out-String -InputObject $_ -Width 2147483647)) 4>&1 | Out-Default 27 | Write-Verbose -Message 'Script stack trace:' 4>&1 | Out-Default 28 | Write-Verbose -Message "$($_.ScriptStackTrace)" 4>&1 | Out-Default 29 | Write-Verbose -Message 'Exception:' 4>&1 | Out-Default 30 | Write-Verbose -Message $_.Exception.ToString() 4>&1 | Out-Default 31 | Write-TaskError -Message $_.Exception.Message 32 | } elseif ($_ -is [System.Management.Automation.WarningRecord]) { 33 | Write-TaskWarning -Message (Remove-TrailingNewLine (Out-String -InputObject $_ -Width 2147483647)) 34 | } elseif ($_ -is [System.Management.Automation.VerboseRecord] -and !$global:__vstsNoOverrideVerbose) { 35 | foreach ($private:str in (Format-DebugMessage -Object $_)) { 36 | Write-TaskVerbose -Message $private:str 37 | } 38 | } elseif ($_ -is [System.Management.Automation.DebugRecord] -and !$global:__vstsNoOverrideVerbose) { 39 | foreach ($private:str in (Format-DebugMessage -Object $_)) { 40 | Write-TaskDebug -Message $private:str 41 | } 42 | } else { 43 | # TODO: Consider using out-string here to control the width. As a security precaution it would actually be best to set it to max so wrapping doesn't interfere with secret masking. 44 | $__sp.Process($_) 45 | } 46 | 47 | #Write-Host '[Leaving Process Out-Default]' 48 | } 49 | 50 | end { 51 | #Write-Host '[Entering End Out-Default]' 52 | $__sp.End() 53 | #Write-Host '[Leaving End Out-Default]' 54 | } 55 | } 56 | 57 | ######################################## 58 | # Private functions. 59 | ######################################## 60 | function Format-DebugMessage { 61 | [CmdletBinding()] 62 | param([psobject]$Object) 63 | 64 | $private:str = Out-String -InputObject $Object -Width 2147483647 65 | $private:str = Remove-TrailingNewLine $private:str 66 | "$private:str".Replace("`r`n", "`n").Replace("`r", "`n").Split("`n"[0]) 67 | } 68 | 69 | function Remove-TrailingNewLine { 70 | [CmdletBinding()] 71 | param($Str) 72 | if ([object]::ReferenceEquals($Str, $null)) { 73 | return $Str 74 | } elseif ($Str.EndsWith("`r`n")) { 75 | return $Str.Substring(0, $Str.Length - 2) 76 | } else { 77 | return $Str 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/PSGetModuleInfo.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/PSGetModuleInfo.xml -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/Strings/resources.resjson/de-de/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "Agentversion {0} oder höher ist erforderlich.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Der Containerpfad wurde nicht gefunden: \"{0}\".", 4 | "loc.messages.PSLIB_EndpointAuth0": "\"{0}\"-Dienstendpunkt-Anmeldeinformationen", 5 | "loc.messages.PSLIB_EndpointUrl0": "\"{0}\"-Dienstendpunkt-URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Fehler beim Aufzählen von Unterverzeichnissen für den folgenden Pfad: \"{0}\"", 7 | "loc.messages.PSLIB_FileNotFound0": "Die Datei wurde nicht gefunden: \"{0}\".", 8 | "loc.messages.PSLIB_Input0": "\"{0}\"-Eingabe", 9 | "loc.messages.PSLIB_InvalidPattern0": "Ungültiges Muster: \"{0}\"", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Der Blattpfad wurde nicht gefunden: \"{0}\".", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "Fehler bei der Normalisierung bzw. Erweiterung des Pfads. Die Pfadlänge wurde vom Kernel32-Subsystem nicht zurückgegeben für: \"{0}\"", 12 | "loc.messages.PSLIB_PathNotFound0": "Der Pfad wurde nicht gefunden: \"{0}\".", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Der Prozess \"{0}\" wurde mit dem Code \"{1}\" beendet.", 14 | "loc.messages.PSLIB_Required0": "Erforderlich: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Fehler beim Zeichenfolgenformat.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "Der Zeichenfolgen-Ressourcenschlüssel wurde nicht gefunden: \"{0}\".", 17 | "loc.messages.PSLIB_TaskVariable0": "\"{0}\"-Taskvariable" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/Strings/resources.resjson/en-US/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "Agent version {0} or higher is required.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Container path not found: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "'{0}' service endpoint credentials", 5 | "loc.messages.PSLIB_EndpointUrl0": "'{0}' service endpoint URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Enumerating subdirectories failed for path: '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "File not found: '{0}'", 8 | "loc.messages.PSLIB_Input0": "'{0}' input", 9 | "loc.messages.PSLIB_InvalidPattern0": "Invalid pattern: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Leaf path not found: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "Path normalization/expansion failed. The path length was not returned by the Kernel32 subsystem for: '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "Path not found: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Process '{0}' exited with code '{1}'.", 14 | "loc.messages.PSLIB_Required0": "Required: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "String format failed.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "String resource key not found: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "'{0}' task variable" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/Strings/resources.resjson/es-es/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "Se require la versión {0} o posterior del agente.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "No se encuentra la ruta de acceso del contenedor: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "Credenciales del punto de conexión de servicio '{0}'", 5 | "loc.messages.PSLIB_EndpointUrl0": "URL del punto de conexión de servicio '{0}'", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "No se pudieron enumerar los subdirectorios de la ruta de acceso: '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "Archivo no encontrado: '{0}'", 8 | "loc.messages.PSLIB_Input0": "Entrada '{0}'", 9 | "loc.messages.PSLIB_InvalidPattern0": "Patrón no válido: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "No se encuentra la ruta de acceso de la hoja: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "No se pudo normalizar o expandir la ruta de acceso. El subsistema Kernel32 no devolvió la longitud de la ruta de acceso para: '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "No se encuentra la ruta de acceso: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "El proceso '{0}' finalizó con el código '{1}'.", 14 | "loc.messages.PSLIB_Required0": "Se requiere: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Error de formato de cadena.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "No se encuentra la clave de recurso de la cadena: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "Variable de tarea '{0}'" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/Strings/resources.resjson/fr-fr/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "L'agent version {0} (ou une version ultérieure) est obligatoire.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Le chemin du conteneur est introuvable : '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "Informations d'identification du point de terminaison de service '{0}'", 5 | "loc.messages.PSLIB_EndpointUrl0": "URL du point de terminaison de service '{0}'", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Échec de l'énumération des sous-répertoires pour le chemin : '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "Fichier introuvable : {0}.", 8 | "loc.messages.PSLIB_Input0": "Entrée '{0}'", 9 | "loc.messages.PSLIB_InvalidPattern0": "Modèle non valide : '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Le chemin feuille est introuvable : '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "Échec de la normalisation/l'expansion du chemin. La longueur du chemin n'a pas été retournée par le sous-système Kernel32 pour : '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "Chemin introuvable : '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Le processus '{0}' s'est arrêté avec le code '{1}'.", 14 | "loc.messages.PSLIB_Required0": "Obligatoire : {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Échec du format de la chaîne.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "Clé de la ressource de type chaîne introuvable : '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "Variable de tâche '{0}'" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/Strings/resources.resjson/it-IT/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "È richiesta la versione dell'agente {0} o superiore.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Percorso del contenitore non trovato: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "Credenziali dell'endpoint servizio '{0}'", 5 | "loc.messages.PSLIB_EndpointUrl0": "URL dell'endpoint servizio '{0}'", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "L'enumerazione delle sottodirectory per il percorso '{0}' non è riuscita", 7 | "loc.messages.PSLIB_FileNotFound0": "File non trovato: '{0}'", 8 | "loc.messages.PSLIB_Input0": "Input di '{0}'", 9 | "loc.messages.PSLIB_InvalidPattern0": "Criterio non valido: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Percorso foglia non trovato: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "La normalizzazione o l'espansione del percorso non è riuscita. Il sottosistema Kernel32 non ha restituito la lunghezza del percorso per '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "Percorso non trovato: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Il processo '{0}' è stato terminato ed è stato restituito il codice '{1}'.", 14 | "loc.messages.PSLIB_Required0": "Obbligatorio: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Errore nel formato della stringa.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "La chiave della risorsa stringa non è stata trovata: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "Variabile dell'attività '{0}'" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/Strings/resources.resjson/ja-jp/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "バージョン {0} 以降のエージェントが必要です。", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "コンテナーのパスが見つかりません: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "'{0}' サービス エンドポイントの資格情報", 5 | "loc.messages.PSLIB_EndpointUrl0": "'{0}' サービス エンドポイントの URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "パス '{0}' のサブディレクトリを列挙できませんでした", 7 | "loc.messages.PSLIB_FileNotFound0": "ファイルが見つかりません: '{0}'", 8 | "loc.messages.PSLIB_Input0": "'{0}' 入力", 9 | "loc.messages.PSLIB_InvalidPattern0": "使用できないパターンです: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "リーフ パスが見つかりません: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "パスの正規化/展開に失敗しました。Kernel32 サブシステムからパス '{0}' の長さが返されませんでした", 12 | "loc.messages.PSLIB_PathNotFound0": "パスが見つかりません: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "プロセス '{0}' がコード '{1}' で終了しました。", 14 | "loc.messages.PSLIB_Required0": "必要: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "文字列のフォーマットに失敗しました。", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "文字列のリソース キーが見つかりません: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "'{0}' タスク変数" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/Strings/resources.resjson/ko-KR/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "에이전트 버전 {0} 이상이 필요합니다.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "컨테이너 경로를 찾을 수 없음: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "'{0}' 서비스 끝점 자격 증명", 5 | "loc.messages.PSLIB_EndpointUrl0": "'{0}' 서비스 끝점 URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "경로에 대해 하위 디렉터리를 열거하지 못함: '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "{0} 파일을 찾을 수 없습니다.", 8 | "loc.messages.PSLIB_Input0": "'{0}' 입력", 9 | "loc.messages.PSLIB_InvalidPattern0": "잘못된 패턴: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Leaf 경로를 찾을 수 없음: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "경로 정규화/확장에 실패했습니다. 다음에 대해 Kernel32 subsystem에서 경로 길이를 반환하지 않음: '{0}'", 12 | "loc.messages.PSLIB_PathNotFound0": "경로를 찾을 수 없음: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "'{1}' 코드로 '{0}' 프로세스가 종료되었습니다.", 14 | "loc.messages.PSLIB_Required0": "필수: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "문자열을 포맷하지 못했습니다.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "문자열 리소스 키를 찾을 수 없음: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "'{0}' 작업 변수" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/Strings/resources.resjson/ru-RU/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "Требуется версия агента {0} или более поздняя.", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "Путь к контейнеру не найден: \"{0}\".", 4 | "loc.messages.PSLIB_EndpointAuth0": "Учетные данные конечной точки службы \"{0}\"", 5 | "loc.messages.PSLIB_EndpointUrl0": "URL-адрес конечной точки службы \"{0}\"", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Сбой перечисления подкаталогов для пути: \"{0}\".", 7 | "loc.messages.PSLIB_FileNotFound0": "Файл не найден: \"{0}\".", 8 | "loc.messages.PSLIB_Input0": "Входные данные \"{0}\".", 9 | "loc.messages.PSLIB_InvalidPattern0": "Недопустимый шаблон: \"{0}\".", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "Путь к конечному объекту не найден: \"{0}\".", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "Сбой нормализации и расширения пути. Длина пути не была возвращена подсистемой Kernel32 для: \"{0}\".", 12 | "loc.messages.PSLIB_PathNotFound0": "Путь не найден: \"{0}\".", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "Процесс \"{0}\" завершил работу с кодом \"{1}\".", 14 | "loc.messages.PSLIB_Required0": "Требуется: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "Сбой формата строки.", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "Ключ ресурса строки не найден: \"{0}\".", 17 | "loc.messages.PSLIB_TaskVariable0": "Переменная задачи \"{0}\"" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/Strings/resources.resjson/zh-CN/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "需要代理版本 {0} 或更高版本。", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "找不到容器路径:“{0}”", 4 | "loc.messages.PSLIB_EndpointAuth0": "“{0}”服务终结点凭据", 5 | "loc.messages.PSLIB_EndpointUrl0": "“{0}”服务终结点 URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "枚举路径的子目录失败:“{0}”", 7 | "loc.messages.PSLIB_FileNotFound0": "找不到文件: {0}。", 8 | "loc.messages.PSLIB_Input0": "“{0}”输入", 9 | "loc.messages.PSLIB_InvalidPattern0": "无效的模式:“{0}”", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "找不到叶路径:“{0}”", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "路径规范化/扩展失败。路径长度不是由“{0}”的 Kernel32 子系统返回的", 12 | "loc.messages.PSLIB_PathNotFound0": "找不到路径:“{0}”", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "过程“{0}”已退出,代码为“{1}”。", 14 | "loc.messages.PSLIB_Required0": "必需: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "字符串格式无效。", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "找不到字符串资源关键字:“{0}”", 17 | "loc.messages.PSLIB_TaskVariable0": "“{0}”任务变量" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/Strings/resources.resjson/zh-TW/resources.resjson: -------------------------------------------------------------------------------- 1 | { 2 | "loc.messages.PSLIB_AgentVersion0Required": "需要代理程式版本 {0} 或更新的版本。", 3 | "loc.messages.PSLIB_ContainerPathNotFound0": "找不到容器路徑: '{0}'", 4 | "loc.messages.PSLIB_EndpointAuth0": "'{0}' 服務端點認證", 5 | "loc.messages.PSLIB_EndpointUrl0": "'{0}' 服務端點 URL", 6 | "loc.messages.PSLIB_EnumeratingSubdirectoriesFailedForPath0": "為路徑列舉子目錄失敗: '{0}'", 7 | "loc.messages.PSLIB_FileNotFound0": "找不到檔案: '{0}'", 8 | "loc.messages.PSLIB_Input0": "'{0}' 輸入", 9 | "loc.messages.PSLIB_InvalidPattern0": "模式無效: '{0}'", 10 | "loc.messages.PSLIB_LeafPathNotFound0": "找不到分葉路徑: '{0}'", 11 | "loc.messages.PSLIB_PathLengthNotReturnedFor0": "路徑正規化/展開失敗。Kernel32 子系統未傳回 '{0}' 的路徑長度", 12 | "loc.messages.PSLIB_PathNotFound0": "找不到路徑: '{0}'", 13 | "loc.messages.PSLIB_Process0ExitedWithCode1": "處理序 '{0}' 以返回碼 '{1}' 結束。", 14 | "loc.messages.PSLIB_Required0": "必要項: {0}", 15 | "loc.messages.PSLIB_StringFormatFailed": "字串格式失敗。", 16 | "loc.messages.PSLIB_StringResourceKeyNotFound0": "找不到字串資源索引鍵: '{0}'", 17 | "loc.messages.PSLIB_TaskVariable0": "'{0}' 工作變數" 18 | } -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/ToolFunctions.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Asserts the agent version is at least the specified minimum. 4 | 5 | .PARAMETER Minimum 6 | Minimum version - must be 2.104.1 or higher. 7 | #> 8 | function Assert-Agent { 9 | [CmdletBinding()] 10 | param( 11 | [Parameter(Mandatory = $true)] 12 | [version]$Minimum) 13 | 14 | if (([version]'2.104.1').CompareTo($Minimum) -ge 1) { 15 | Write-Error "Assert-Agent requires the parameter to be 2.104.1 or higher." 16 | return 17 | } 18 | 19 | $agent = Get-TaskVariable -Name 'agent.version' 20 | if (!$agent -or $Minimum.CompareTo([version]$agent) -ge 1) { 21 | Write-Error (Get-LocString -Key 'PSLIB_AgentVersion0Required' -ArgumentList $Minimum) 22 | } 23 | } 24 | 25 | <# 26 | .SYNOPSIS 27 | Asserts that a path exists. Throws if the path does not exist. 28 | 29 | .PARAMETER PassThru 30 | True to return the path. 31 | #> 32 | function Assert-Path { 33 | [CmdletBinding()] 34 | param( 35 | [Parameter(Mandatory = $true)] 36 | [string]$LiteralPath, 37 | [Microsoft.PowerShell.Commands.TestPathType]$PathType = [Microsoft.PowerShell.Commands.TestPathType]::Any, 38 | [switch]$PassThru) 39 | 40 | if ($PathType -eq [Microsoft.PowerShell.Commands.TestPathType]::Any) { 41 | Write-Verbose "Asserting path exists: '$LiteralPath'" 42 | } else { 43 | Write-Verbose "Asserting $("$PathType".ToLowerInvariant()) path exists: '$LiteralPath'" 44 | } 45 | 46 | if (Test-Path -LiteralPath $LiteralPath -PathType $PathType) { 47 | if ($PassThru) { 48 | return $LiteralPath 49 | } 50 | 51 | return 52 | } 53 | 54 | $resourceKey = switch ($PathType) { 55 | ([Microsoft.PowerShell.Commands.TestPathType]::Container) { "PSLIB_ContainerPathNotFound0" ; break } 56 | ([Microsoft.PowerShell.Commands.TestPathType]::Leaf) { "PSLIB_LeafPathNotFound0" ; break } 57 | default { "PSLIB_PathNotFound0" } 58 | } 59 | 60 | throw (Get-LocString -Key $resourceKey -ArgumentList $LiteralPath) 61 | } 62 | 63 | <# 64 | .SYNOPSIS 65 | Executes an external program. 66 | 67 | .DESCRIPTION 68 | Executes an external program and waits for the process to exit. 69 | 70 | After calling this command, the exit code of the process can be retrieved from the variable $LASTEXITCODE. 71 | 72 | .PARAMETER Encoding 73 | This parameter not required for most scenarios. Indicates how to interpret the encoding from the external program. An example use case would be if an external program outputs UTF-16 XML and the output needs to be parsed. 74 | 75 | .PARAMETER RequireExitCodeZero 76 | Indicates whether to write an error to the error pipeline if the exit code is not zero. 77 | #> 78 | function Invoke-Tool { # TODO: RENAME TO INVOKE-PROCESS? 79 | [CmdletBinding()] 80 | param( 81 | [ValidatePattern('^[^\r\n]*$')] 82 | [Parameter(Mandatory = $true)] 83 | [string]$FileName, 84 | [ValidatePattern('^[^\r\n]*$')] 85 | [Parameter()] 86 | [string]$Arguments, 87 | [string]$WorkingDirectory, 88 | [System.Text.Encoding]$Encoding, 89 | [switch]$RequireExitCodeZero) 90 | 91 | Trace-EnteringInvocation $MyInvocation 92 | $isPushed = $false 93 | $originalEncoding = $null 94 | try { 95 | if ($Encoding) { 96 | $originalEncoding = [System.Console]::OutputEncoding 97 | [System.Console]::OutputEncoding = $Encoding 98 | } 99 | 100 | if ($WorkingDirectory) { 101 | Push-Location -LiteralPath $WorkingDirectory -ErrorAction Stop 102 | $isPushed = $true 103 | } 104 | 105 | $FileName = $FileName.Replace('"', '').Replace("'", "''") 106 | Write-Host "##[command]""$FileName"" $Arguments" 107 | Invoke-Expression "& '$FileName' --% $Arguments" 108 | Write-Verbose "Exit code: $LASTEXITCODE" 109 | if ($RequireExitCodeZero -and $LASTEXITCODE -ne 0) { 110 | Write-Error (Get-LocString -Key PSLIB_Process0ExitedWithCode1 -ArgumentList ([System.IO.Path]::GetFileName($FileName)), $LASTEXITCODE) 111 | } 112 | } finally { 113 | if ($originalEncoding) { 114 | [System.Console]::OutputEncoding = $originalEncoding 115 | } 116 | 117 | if ($isPushed) { 118 | Pop-Location 119 | } 120 | 121 | Trace-LeavingInvocation $MyInvocation 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/TraceFunctions.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Writes verbose information about the invocation being entered. 4 | 5 | .DESCRIPTION 6 | Used to trace verbose information when entering a function/script. Writes an entering message followed by a short description of the invocation. Additionally each bound parameter and unbound argument is also traced. 7 | 8 | .PARAMETER Parameter 9 | Wildcard pattern to control which bound parameters are traced. 10 | #> 11 | function Trace-EnteringInvocation { 12 | [CmdletBinding()] 13 | param( 14 | [Parameter(Mandatory = $true)] 15 | [System.Management.Automation.InvocationInfo]$InvocationInfo, 16 | [string[]]$Parameter = '*') 17 | 18 | Write-Verbose "Entering $(Get-InvocationDescription $InvocationInfo)." 19 | $OFS = ", " 20 | if ($InvocationInfo.BoundParameters.Count -and $Parameter.Count) { 21 | if ($Parameter.Count -eq 1 -and $Parameter[0] -eq '*') { 22 | # Trace all parameters. 23 | foreach ($key in $InvocationInfo.BoundParameters.Keys) { 24 | Write-Verbose " $($key): '$($InvocationInfo.BoundParameters[$key])'" 25 | } 26 | } else { 27 | # Trace matching parameters. 28 | foreach ($key in $InvocationInfo.BoundParameters.Keys) { 29 | foreach ($p in $Parameter) { 30 | if ($key -like $p) { 31 | Write-Verbose " $($key): '$($InvocationInfo.BoundParameters[$key])'" 32 | break 33 | } 34 | } 35 | } 36 | } 37 | } 38 | 39 | # Trace all unbound arguments. 40 | if (@($InvocationInfo.UnboundArguments).Count) { 41 | for ($i = 0 ; $i -lt $InvocationInfo.UnboundArguments.Count ; $i++) { 42 | Write-Verbose " args[$i]: '$($InvocationInfo.UnboundArguments[$i])'" 43 | } 44 | } 45 | } 46 | 47 | <# 48 | .SYNOPSIS 49 | Writes verbose information about the invocation being left. 50 | 51 | .DESCRIPTION 52 | Used to trace verbose information when leaving a function/script. Writes a leaving message followed by a short description of the invocation. 53 | #> 54 | function Trace-LeavingInvocation { 55 | [CmdletBinding()] 56 | param( 57 | [Parameter(Mandatory = $true)] 58 | [System.Management.Automation.InvocationInfo]$InvocationInfo) 59 | 60 | Write-Verbose "Leaving $(Get-InvocationDescription $InvocationInfo)." 61 | } 62 | 63 | <# 64 | .SYNOPSIS 65 | Writes verbose information about paths. 66 | 67 | .DESCRIPTION 68 | Writes verbose information about the paths. The paths are sorted and a the common root is written only once, followed by each relative path. 69 | 70 | .PARAMETER PassThru 71 | Indicates whether to return the sorted paths. 72 | #> 73 | function Trace-Path { 74 | [CmdletBinding()] 75 | param( 76 | [string[]]$Path, 77 | [switch]$PassThru) 78 | 79 | if ($Path.Count -eq 0) { 80 | Write-Verbose "No paths." 81 | if ($PassThru) { 82 | $Path 83 | } 84 | } elseif ($Path.Count -eq 1) { 85 | Write-Verbose "Path: $($Path[0])" 86 | if ($PassThru) { 87 | $Path 88 | } 89 | } else { 90 | # Find the greatest common root. 91 | $sorted = $Path | Sort-Object 92 | $firstPath = $sorted[0].ToCharArray() 93 | $lastPath = $sorted[-1].ToCharArray() 94 | $commonEndIndex = 0 95 | $j = if ($firstPath.Length -lt $lastPath.Length) { $firstPath.Length } else { $lastPath.Length } 96 | for ($i = 0 ; $i -lt $j ; $i++) { 97 | if ($firstPath[$i] -eq $lastPath[$i]) { 98 | if ($firstPath[$i] -eq '\') { 99 | $commonEndIndex = $i 100 | } 101 | } else { 102 | break 103 | } 104 | } 105 | 106 | if ($commonEndIndex -eq 0) { 107 | # No common root. 108 | Write-Verbose "Paths:" 109 | foreach ($p in $sorted) { 110 | Write-Verbose " $p" 111 | } 112 | } else { 113 | Write-Verbose "Paths: $($Path[0].Substring(0, $commonEndIndex + 1))" 114 | foreach ($p in $sorted) { 115 | Write-Verbose " $($p.Substring($commonEndIndex + 1))" 116 | } 117 | } 118 | 119 | if ($PassThru) { 120 | $sorted 121 | } 122 | } 123 | } 124 | 125 | ######################################## 126 | # Private functions. 127 | ######################################## 128 | function Get-InvocationDescription { 129 | [CmdletBinding()] 130 | param([System.Management.Automation.InvocationInfo]$InvocationInfo) 131 | 132 | if ($InvocationInfo.MyCommand.Path) { 133 | $InvocationInfo.MyCommand.Path 134 | } elseif ($InvocationInfo.MyCommand.Name) { 135 | $InvocationInfo.MyCommand.Name 136 | } else { 137 | $InvocationInfo.MyCommand.CommandType 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/VstsTaskSdk.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/VstsTaskSdk.dll -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/VstsTaskSdk.psd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dejulia489/WindowsServiceManager/7e5e36ca3b57952f97edd2515c3c4451532c8297/WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/VstsTaskSdk.psd1 -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/VstsTaskSdk.psm1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | [ValidateNotNull()] 4 | [Parameter()] 5 | [hashtable]$ModuleParameters = @{ }) 6 | 7 | if ($host.Name -ne 'ConsoleHost') { 8 | Write-Warning "VstsTaskSdk is designed for use with powershell.exe (ConsoleHost). Output may be different when used with other hosts." 9 | } 10 | 11 | # Private module variables. 12 | [bool]$script:nonInteractive = "$($ModuleParameters['NonInteractive'])" -eq 'true' 13 | Write-Verbose "NonInteractive: $script:nonInteractive" 14 | 15 | # VstsTaskSdk.dll contains the TerminationException and NativeMethods for handle long path 16 | # We used to do inline C# in this powershell module 17 | # However when csc compile the inline C#, it will hit process env block size limit since it's not use unicode to encode env 18 | # To solve the env block size problem, we choose to put all inline C# into an assembly VstsTaskSdk.dll, signing it, package with the PS modules. 19 | Write-Verbose "Loading compiled helper $PSScriptRoot\VstsTaskSdk.dll." 20 | Add-Type -LiteralPath $PSScriptRoot\VstsTaskSdk.dll 21 | 22 | # Import/export functions. 23 | . "$PSScriptRoot\FindFunctions.ps1" 24 | . "$PSScriptRoot\InputFunctions.ps1" 25 | . "$PSScriptRoot\LegacyFindFunctions.ps1" 26 | . "$PSScriptRoot\LocalizationFunctions.ps1" 27 | . "$PSScriptRoot\LoggingCommandFunctions.ps1" 28 | . "$PSScriptRoot\LongPathFunctions.ps1" 29 | . "$PSScriptRoot\ServerOMFunctions.ps1" 30 | . "$PSScriptRoot\ToolFunctions.ps1" 31 | . "$PSScriptRoot\TraceFunctions.ps1" 32 | . "$PSScriptRoot\OutFunctions.ps1" # Load the out functions after all of the other functions are loaded. 33 | Export-ModuleMember -Function @( 34 | # Find functions. 35 | 'Find-Match' 36 | 'New-FindOptions' 37 | 'New-MatchOptions' 38 | 'Select-Match' 39 | # Input functions. 40 | 'Get-Endpoint' 41 | 'Get-SecureFileTicket' 42 | 'Get-SecureFileName' 43 | 'Get-Input' 44 | 'Get-TaskVariable' 45 | 'Get-TaskVariableInfo' 46 | 'Set-TaskVariable' 47 | # Legacy find functions. 48 | 'Find-Files' 49 | # Localization functions. 50 | 'Get-LocString' 51 | 'Import-LocStrings' 52 | # Logging command functions. 53 | 'Write-AddAttachment' 54 | 'Write-AddBuildTag' 55 | 'Write-AssociateArtifact' 56 | 'Write-LogDetail' 57 | 'Write-PrependPath' 58 | 'Write-SetEndpoint' 59 | 'Write-SetProgress' 60 | 'Write-SetResult' 61 | 'Write-SetSecret' 62 | 'Write-SetVariable' 63 | 'Write-TaskDebug' 64 | 'Write-TaskError' 65 | 'Write-TaskVerbose' 66 | 'Write-TaskWarning' 67 | 'Write-UpdateBuildNumber' 68 | 'Write-UpdateReleaseName' 69 | 'Write-UploadArtifact' 70 | 'Write-UploadBuildLog' 71 | 'Write-UploadFile' 72 | 'Write-UploadSummary' 73 | # Out functions. 74 | 'Out-Default' 75 | # Server OM functions. 76 | 'Get-AssemblyReference' 77 | 'Get-TfsClientCredentials' 78 | 'Get-TfsService' 79 | 'Get-VssCredentials' 80 | 'Get-VssHttpClient' 81 | # Tool functions. 82 | 'Assert-Agent' 83 | 'Assert-Path' 84 | 'Invoke-Tool' 85 | # Trace functions. 86 | 'Trace-EnteringInvocation' 87 | 'Trace-LeavingInvocation' 88 | 'Trace-Path' 89 | # Proxy functions 90 | 'Get-WebProxy' 91 | # Client cert functions 92 | 'Get-ClientCertificate' 93 | ) 94 | 95 | # Override Out-Default globally. 96 | $null = New-Item -Force -Path "function:\global:Out-Default" -Value (Get-Command -CommandType Function -Name Out-Default -ListImported) 97 | New-Alias -Name Out-Default -Value "global:Out-Default" -Scope global 98 | 99 | # Perform some initialization in a script block to enable merging the pipelines. 100 | $scriptText = @" 101 | # Load the SDK resource strings. 102 | Import-LocStrings "$PSScriptRoot\lib.json" 103 | 104 | # Load the module that contains ConvertTo-SecureString. 105 | if (!(Get-Module -Name Microsoft.PowerShell.Security)) { 106 | Write-Verbose "Importing the module 'Microsoft.PowerShell.Security'." 107 | Import-Module -Name Microsoft.PowerShell.Security 2>&1 | 108 | ForEach-Object { 109 | if (`$_ -is [System.Management.Automation.ErrorRecord]) { 110 | Write-Verbose `$_.Exception.Message 111 | } else { 112 | ,`$_ 113 | } 114 | } 115 | } 116 | "@ 117 | . ([scriptblock]::Create($scriptText)) 2>&1 3>&1 4>&1 5>&1 | Out-Default 118 | 119 | # Create Invoke-VstsTaskScript in a special way so it is not bound to the module. 120 | # Otherwise calling the task script block would run within the module context. 121 | # 122 | # An alternative way to solve the problem is to close the script block (i.e. closure). 123 | # However, that introduces a different problem. Closed script blocks are created within 124 | # a dynamic module. Each module gets it's own session state separate from the global 125 | # session state. When running in a regular script context, Import-Module calls import 126 | # the target module into the global session state. When running in a module context, 127 | # Import-Module calls import the target module into the caller module's session state. 128 | # 129 | # The goal of a task may include executing ad-hoc scripts. Therefore, task scripts 130 | # should run in regular script context. The end user specifying an ad-hoc script expects 131 | # the module import rules to be consistent with the default behavior (i.e. imported 132 | # into the global session state). 133 | $null = New-Item -Force -Path "function:\global:Invoke-VstsTaskScript" -Value ([scriptblock]::Create(@' 134 | [CmdletBinding()] 135 | param( 136 | [Parameter(Mandatory = $true)] 137 | [scriptblock]$ScriptBlock) 138 | 139 | try { 140 | $global:ErrorActionPreference = 'Stop' 141 | 142 | # Initialize the environment. 143 | $vstsModule = Get-Module -Name VstsTaskSdk 144 | Write-Verbose "$($vstsModule.Name) $($vstsModule.Version) commit $($vstsModule.PrivateData.PSData.CommitHash)" 4>&1 | Out-Default 145 | & $vstsModule Initialize-Inputs 4>&1 | Out-Default 146 | 147 | # Remove the local variable before calling the user's script. 148 | Remove-Variable -Name vstsModule 149 | 150 | # Call the user's script. 151 | $ScriptBlock | 152 | ForEach-Object { 153 | # Remove the scriptblock variable before calling it. 154 | Remove-Variable -Name ScriptBlock 155 | & $_ 2>&1 3>&1 4>&1 5>&1 | Out-Default 156 | } 157 | } catch [VstsTaskSdk.TerminationException] { 158 | # Special internal exception type to control the flow. Not currently intended 159 | # for public usage and subject to change. 160 | $global:__vstsNoOverrideVerbose = '' 161 | Write-Verbose "Task script terminated." 4>&1 | Out-Default 162 | } catch { 163 | $global:__vstsNoOverrideVerbose = '' 164 | Write-Verbose "Caught exception from task script." 4>&1 | Out-Default 165 | $_ | Out-Default 166 | Write-Host "##vso[task.complete result=Failed]" 167 | } 168 | '@)) 169 | -------------------------------------------------------------------------------- /WindowsServiceManager/WindowsServiceManagerV4/ps_modules/VstsTaskSdk/lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "messages": { 3 | "PSLIB_AgentVersion0Required": "Agent version {0} or higher is required.", 4 | "PSLIB_ContainerPathNotFound0": "Container path not found: '{0}'", 5 | "PSLIB_EndpointAuth0": "'{0}' service endpoint credentials", 6 | "PSLIB_EndpointUrl0": "'{0}' service endpoint URL", 7 | "PSLIB_EnumeratingSubdirectoriesFailedForPath0": "Enumerating subdirectories failed for path: '{0}'", 8 | "PSLIB_FileNotFound0": "File not found: '{0}'", 9 | "PSLIB_Input0": "'{0}' input", 10 | "PSLIB_InvalidPattern0": "Invalid pattern: '{0}'", 11 | "PSLIB_LeafPathNotFound0": "Leaf path not found: '{0}'", 12 | "PSLIB_PathLengthNotReturnedFor0": "Path normalization/expansion failed. The path length was not returned by the Kernel32 subsystem for: '{0}'", 13 | "PSLIB_PathNotFound0": "Path not found: '{0}'", 14 | "PSLIB_Process0ExitedWithCode1": "Process '{0}' exited with code '{1}'.", 15 | "PSLIB_Required0": "Required: {0}", 16 | "PSLIB_StringFormatFailed": "String format failed.", 17 | "PSLIB_StringResourceKeyNotFound0": "String resource key not found: '{0}'", 18 | "PSLIB_TaskVariable0": "'{0}' task variable" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /vss-extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": 1, 3 | "id": "WindowsServiceManager", 4 | "version": "1.0.0", 5 | "name": "Windows Service Manager", 6 | "description": "Installs and deploys a windows service or TopShelf service on a target machine or a deployment group target.", 7 | "publisher": "MDSolutions", 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/Dejulia489/WindowsServiceManager" 11 | }, 12 | "links": { 13 | "support": "https://github.com/Dejulia489/WindowsServiceManager" 14 | }, 15 | "screenshots": [ 16 | { 17 | "path": "Images\\TaskOptionsDeploymentGroup.png" 18 | }, 19 | { 20 | "path": "Images\\TaskOptionsAgent.png" 21 | }, 22 | { 23 | "path": "Images\\TaskOptionsAdvanced.png" 24 | }, 25 | { 26 | "path": "Images\\TaskOptionsInstallation.png" 27 | }, 28 | { 29 | "path": "Images\\Task.png" 30 | } 31 | ], 32 | "content": { 33 | "details": { 34 | "path": "README.md" 35 | } 36 | }, 37 | "tags": [ 38 | "Release Management", 39 | "Azure DevOps Pipelines", 40 | "Windows Service", 41 | "VSTS", 42 | "TopShelf", 43 | "Visual Studio Team Services" 44 | ], 45 | "license": "MIT", 46 | "targets": [ 47 | { 48 | "id": "Microsoft.VisualStudio.Services" 49 | } 50 | ], 51 | "icons": { 52 | "default": "Images\\icon.png" 53 | }, 54 | "categories": [ 55 | "Azure Pipelines" 56 | ], 57 | "contributions": [ 58 | { 59 | "id": "WindowsServiceManager", 60 | "type": "ms.vss-distributed-task.task", 61 | "targets": [ 62 | "ms.vss-distributed-task.tasks" 63 | ], 64 | "properties": { 65 | "name": "WindowsServiceManager" 66 | } 67 | } 68 | ], 69 | "files": [ 70 | { 71 | "path": "WindowsServiceManager" 72 | } 73 | ] 74 | } --------------------------------------------------------------------------------