mirror of
https://github.com/PowerShell/PSDscResources
synced 2026-06-21 13:45:29 +00:00
adding all service updates
This commit is contained in:
Binary file not shown.
@@ -1,60 +1,28 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
If the service with the name Service1 does not exist, creates the service with the name
|
||||
Service1 and the executable/binary path 'C:\FilePath\MyServiceExecutable.exe'. The new
|
||||
service will be started by default.
|
||||
|
||||
If the service with the name Service1 already exists, sets executable/binary path of the
|
||||
service with the name Service1 to 'C:\FilePath\MyServiceExecutable.exe' and starts the
|
||||
service by default if it is not running already.
|
||||
#>
|
||||
Configuration Sample_Service_CreateService
|
||||
{
|
||||
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[System.String[]]
|
||||
$nodeName = 'localhost',
|
||||
()
|
||||
|
||||
[System.String]
|
||||
$Name,
|
||||
|
||||
[System.String]
|
||||
[ValidateSet('Automatic', 'Manual', 'Disabled')]
|
||||
$StartupType='Automatic',
|
||||
Import-DscResource -ModuleName 'PSDscResources'
|
||||
|
||||
[System.String]
|
||||
[ValidateSet('LocalSystem', 'LocalService', 'NetworkService')]
|
||||
$BuiltInAccount='LocalSystem',
|
||||
|
||||
[System.Management.Automation.PSCredential]
|
||||
$Credential,
|
||||
|
||||
[System.String]
|
||||
[ValidateSet('Running', 'Stopped')]
|
||||
$State='Running',
|
||||
|
||||
[System.String]
|
||||
[ValidateSet('Present', 'Absent')]
|
||||
$Ensure='Present',
|
||||
|
||||
[System.String]
|
||||
$Path,
|
||||
|
||||
[System.String]
|
||||
$DisplayName,
|
||||
|
||||
[System.String]
|
||||
$Description,
|
||||
|
||||
[System.String[]]
|
||||
$Dependencies
|
||||
)
|
||||
|
||||
Import-DscResource -Name MSFT_ServiceResource -ModuleName PSDscResources
|
||||
|
||||
Node $nodeName
|
||||
Node localhost
|
||||
{
|
||||
Service service
|
||||
Service ServiceResource1
|
||||
{
|
||||
Name = $Name
|
||||
Ensure = $Ensure
|
||||
Path = $Path
|
||||
Name = 'Service1'
|
||||
Ensure = 'Present'
|
||||
Path = 'C:\FilePath\MyServiceExecutable.exe'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Sample_Service_CreateService -Name 'Sample Service' -Ensure 'Present' -Path 'C:\DSC\TestService.exe'
|
||||
|
||||
|
||||
|
||||
@@ -1,59 +1,21 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Stops and then removes the service with the name Service1.
|
||||
#>
|
||||
Configuration Sample_Service_DeleteService
|
||||
{
|
||||
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[System.String[]]
|
||||
$nodeName = 'localhost',
|
||||
()
|
||||
|
||||
[System.String]
|
||||
$Name,
|
||||
|
||||
[System.String]
|
||||
[ValidateSet('Automatic', 'Manual', 'Disabled')]
|
||||
$StartupType,
|
||||
Import-DscResource -ModuleName 'PSDscResources'
|
||||
|
||||
[System.String]
|
||||
[ValidateSet('LocalSystem', 'LocalService', 'NetworkService')]
|
||||
$BuiltInAccount,
|
||||
|
||||
[System.Management.Automation.PSCredential]
|
||||
$Credential ,
|
||||
|
||||
[System.String]
|
||||
[ValidateSet('Running', 'Stopped')]
|
||||
$State='Running',
|
||||
|
||||
[System.String]
|
||||
[ValidateSet('Present', 'Absent')]
|
||||
$Ensure='Present',
|
||||
|
||||
[System.String]
|
||||
$Path,
|
||||
|
||||
[System.String]
|
||||
$DisplayName,
|
||||
|
||||
[System.String]
|
||||
$Description,
|
||||
|
||||
[System.String[]]
|
||||
$Dependencies
|
||||
)
|
||||
|
||||
Import-DscResource -Name MSFT_ServiceResource -ModuleName PSDscResources
|
||||
|
||||
Node $nodeName
|
||||
Node localhost
|
||||
{
|
||||
Service service
|
||||
Service ServiceResource1
|
||||
{
|
||||
Name = $Name
|
||||
Ensure = $Ensure
|
||||
Name = 'Service1'
|
||||
Ensure = 'Absent'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Sample_Service_DeleteService -Name 'Sample Service' -Ensure 'Absent'
|
||||
|
||||
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
Configuration Sample_Service_ServiceWithCredential
|
||||
{
|
||||
|
||||
param
|
||||
(
|
||||
[System.String[]]
|
||||
$nodeName = 'localhost',
|
||||
|
||||
[System.String]
|
||||
$Name,
|
||||
|
||||
[System.String]
|
||||
[ValidateSet('Automatic', 'Manual', 'Disabled')]
|
||||
$StartupType='Automatic',
|
||||
|
||||
[System.String]
|
||||
[ValidateSet('LocalSystem', 'LocalService', 'NetworkService')]
|
||||
$BuiltInAccount='LocalSystem',
|
||||
|
||||
[System.Management.Automation.PSCredential]
|
||||
$Credential,
|
||||
|
||||
[System.String]
|
||||
[ValidateSet('Running', 'Stopped')]
|
||||
$State='Running',
|
||||
|
||||
[System.String]
|
||||
[ValidateSet('Present', 'Absent')]
|
||||
$Ensure='Present',
|
||||
|
||||
[System.String]
|
||||
$Path,
|
||||
|
||||
[System.String]
|
||||
$DisplayName,
|
||||
|
||||
[System.String]
|
||||
$Description,
|
||||
|
||||
[System.String[]]
|
||||
$Dependencies
|
||||
)
|
||||
|
||||
Import-DscResource -Name MSFT_ServiceResource -ModuleName PSDscResources
|
||||
|
||||
Node $nodeName
|
||||
{
|
||||
Service service
|
||||
{
|
||||
Name = $Name
|
||||
DisplayName = $DisplayName
|
||||
Ensure = $Ensure
|
||||
Path = $Path
|
||||
StartupType = $StartupType
|
||||
Credential = $credential
|
||||
DesktopInteract = 'False'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# To use the sample(s) with credentials, see blog at http://blogs.msdn.com/b/powershell/archive/2014/01/31/want-to-secure-credentials-in-windows-powershell-desired-state-configuration.aspx
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
If the service with the name Service1 does not exist, this configuration would throw an
|
||||
error since the Path is not included here.
|
||||
|
||||
If the service with the name Service1 already exists, sets the startup type of the service
|
||||
with the name Service1 to Manual and ignores the state that the service is currently in.
|
||||
If State is not specified, the configuration will ensure that the state of the service is
|
||||
Running by default.
|
||||
#>
|
||||
Configuration Sample_Service_UpdateStartupTypeIgnoreState
|
||||
{
|
||||
[CmdletBinding()]
|
||||
param ()
|
||||
|
||||
Import-DscResource -ModuleName 'PSDscResources'
|
||||
|
||||
Node localhost
|
||||
{
|
||||
Service ServiceResource1
|
||||
{
|
||||
Name = 'Service1'
|
||||
Ensure = 'Present'
|
||||
StartupType = 'Manual'
|
||||
State = 'Ignore'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,9 +37,9 @@ Please check out the common DSC Resources [contributing guidelines](https://gith
|
||||
* [Group](#group): Provides a mechanism to manage local groups on a target node.
|
||||
* [Service](#service): Provides a mechanism to configure and manage Windows services on a target node.
|
||||
* [User](#user): Provides a mechanism to manage local users on a target node.
|
||||
* [WindowsFeature](#windowsfeature): Provides a mechanism to install or uninstall windows roles or features on a target node.
|
||||
* [WindowsFeature](#windowsfeature): Provides a mechanism to install or uninstall Windows roles or features on a target node.
|
||||
* [WindowsOptionalFeature](#windowsoptionalfeature): Provides a mechanism to enable or disable optional features on a target node.
|
||||
* [WindowsPackageCab](#windowspackagecab): Provides a mechanism to install or uninstall a package from a windows cabinet (cab) file on a target node.
|
||||
* [WindowsPackageCab](#windowspackagecab): Provides a mechanism to install or uninstall a package from a Windows cabinet (cab) file on a target node.
|
||||
* [WindowsProcess](#windowsprocess): Provides a mechanism to start and stop a Windows process.
|
||||
|
||||
### Resources that Work on Nano Server
|
||||
@@ -111,6 +111,7 @@ None
|
||||
|
||||
* [Create a service](https://github.com/PowerShell/PSDscResources/blob/master/Examples/Sample_Service_CreateService.ps1)
|
||||
* [Delete a service](https://github.com/PowerShell/PSDscResources/blob/master/Examples/Sample_Service_DeleteService.ps1)
|
||||
* [Update a service with StartupType set to 'Ignore'](https://github.com/PowerShell/PSDscResources/blob/master/Examples/Sample_Service_UpdateStartupTypeIgnoreState)
|
||||
|
||||
### User
|
||||
|
||||
@@ -196,11 +197,11 @@ This resource works on Nano Server.
|
||||
|
||||
#### Examples
|
||||
|
||||
* [Enable the specified windows optional feature and output logs to the specified path](https://github.com/PowerShell/PSDscResources/blob/master/Examples/Sample_WindowsOptionalFeature.ps1)
|
||||
* [Enable the specified Windows optional feature and output logs to the specified path](https://github.com/PowerShell/PSDscResources/blob/master/Examples/Sample_WindowsOptionalFeature.ps1)
|
||||
|
||||
### WindowsPackageCab
|
||||
|
||||
Provides a mechanism to install or uninstall a package from a windows cabinet (cab) file on a target node.
|
||||
Provides a mechanism to install or uninstall a package from a Windows cabinet (cab) file on a target node.
|
||||
This resource works on Nano Server.
|
||||
|
||||
#### Requirements
|
||||
@@ -268,6 +269,8 @@ None
|
||||
* CommonTestHelper:
|
||||
* Added Get-AppVeyorAdministratorCredential
|
||||
* Added Set-StrictMode -'Latest' and $errorActionPreference -'Stop'
|
||||
* Service:
|
||||
* Updated resource module, tests, and examples to reflect the changes made in xPSDesiredStateConfiguration
|
||||
|
||||
### 2.1.0.0
|
||||
|
||||
|
||||
@@ -1,14 +1,25 @@
|
||||
<#
|
||||
These tests should only be run in AppVeyor since they currently require the AppVeyor
|
||||
administrator account credential to run.
|
||||
|
||||
Also please note that these tests are currently dependent on each other.
|
||||
They must be run in the order given and if one test fails, subsequent tests will
|
||||
also fail.
|
||||
#>
|
||||
|
||||
if ($PSVersionTable.PSVersion.Major -lt 5 -or $PSVersionTable.PSVersion.Minor -lt 1)
|
||||
{
|
||||
Write-Warning -Message 'Cannot run PSDscResources integration tests on PowerShell versions lower than 5.1'
|
||||
return
|
||||
}
|
||||
|
||||
$script:DscResourceName = 'MSFT_ServiceResource'
|
||||
$errorActionPreference = 'Stop'
|
||||
Set-StrictMode -Version 'Latest'
|
||||
|
||||
Import-Module -Name (Join-Path -Path (Split-Path -Path $PSScriptRoot -Parent) `
|
||||
-ChildPath (Join-Path -Path 'TestHelpers' `
|
||||
-ChildPath 'CommonTestHelper.psm1'))
|
||||
# Import CommonTestHelper for Enter-DscResourceTestEnvironment, Exit-DscResourceTestEnvironment
|
||||
$script:moduleRootPath = Split-Path -Path $PSScriptRoot -Parent
|
||||
$script:testHelpersPath = Join-Path -Path $script:moduleRootPath -ChildPath 'TestHelpers'
|
||||
Import-Module -Name (Join-Path -Path $script:testHelpersPath -ChildPath 'CommonTestHelper.psm1')
|
||||
|
||||
$script:testEnvironment = Enter-DscResourceTestEnvironment `
|
||||
-DscResourceModuleName 'PSDscResources' `
|
||||
@@ -17,174 +28,386 @@ $script:testEnvironment = Enter-DscResourceTestEnvironment `
|
||||
|
||||
try
|
||||
{
|
||||
$script:testServiceName = 'DscTestService'
|
||||
$script:testServiceCodePath = Join-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -ChildPath 'TestHelpers\DscTestService.cs'
|
||||
$script:testServiceDisplayName = 'DSC test service display name'
|
||||
$script:testServiceDescription = 'This is a DSC test service used for integration testing MSFT_ServiceResource'
|
||||
$script:testServiceDependsOn = 'winrm'
|
||||
$script:testServiceExecutablePath = Join-Path -Path $ENV:Temp -ChildPath 'DscTestService.exe'
|
||||
$script:testServiceNewCodePath = Join-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -ChildPath 'TestHelpers\DscTestService.cs'
|
||||
$script:testServiceNewDisplayName = 'New: DSC test service display name'
|
||||
$script:testServiceNewDescription = 'New: This is a DSC test service used for integration testing MSFT_ServiceResource'
|
||||
$script:testServiceNewDependsOn = 'spooler'
|
||||
$script:testServiceNewExecutablePath = Join-Path -Path $ENV:Temp -ChildPath 'NewDscTestService.exe'
|
||||
|
||||
<#
|
||||
Nano Server doesn't recognize 'spooler', so if these tests are being run on Nano
|
||||
this value must stay as 'winrm'
|
||||
#>
|
||||
if ($PSVersionTable.PSEdition -ieq 'Core') { $script:testServiceNewDependsOn = 'winrm' }
|
||||
Describe 'Service Integration Tests' {
|
||||
BeforeAll {
|
||||
# Import CommonResourceHelper for Test-IsNanoServer, Get-AppveyorAdministratorCredential
|
||||
$moduleRootFilePath = Split-Path -Path $script:testsFolderFilePath -Parent
|
||||
$dscResourcesFolderFilePath = Join-Path -Path $moduleRootFilePath -ChildPath 'DscResources'
|
||||
$commonResourceHelperFilePath = Join-Path -Path $dscResourcesFolderFilePath -ChildPath 'CommonResourceHelper.psm1'
|
||||
Import-Module -Name $commonResourceHelperFilePath
|
||||
|
||||
Import-Module -Name (Join-Path -Path (Split-Path -Path $PSScriptRoot -Parent) `
|
||||
-ChildPath 'TestHelpers\MSFT_ServiceResource.TestHelper.psm1') `
|
||||
-Force
|
||||
# Import DscResource.Tests TestHelper for Reset-Dsc
|
||||
$dscResourceTestsFilePath = Join-Path -Path $moduleRootFilePath -ChildPath 'DscResource.Tests'
|
||||
$dscResourceTestHelperFilePath = Join-Path -Path $dscResourceTestsFilePath -ChildPath 'TestHelper.psm1'
|
||||
Import-Module -Name $dscResourceTestHelperFilePath
|
||||
|
||||
Stop-Service $script:testServiceName -ErrorAction SilentlyContinue
|
||||
# Import Service test helper for New-ServiceBinary, Test-ServiceExists, Remove-ServiceWithTimeout
|
||||
$serviceTestHelperFilePath = Join-Path -Path $script:testsHelpersFilePath -ChildPath 'MSFT_ServiceResource.TestHelper.psm1'
|
||||
Import-Module -Name $serviceTestHelperFilePath
|
||||
|
||||
# Create new Service binaries for the new service.
|
||||
New-ServiceBinary `
|
||||
-ServiceName $script:testServiceName `
|
||||
-ServiceCodePath $script:testServiceCodePath `
|
||||
-ServiceDisplayName $script:testServiceDisplayName `
|
||||
-ServiceDescription $script:testServiceDescription `
|
||||
-ServiceDependsOn $script:testServiceDependsOn `
|
||||
-ServiceExecutablePath $script:testServiceExecutablePath
|
||||
# Import Service resource module for Test-TargetResource
|
||||
$serviceResourceFolderFilePath = Join-Path -Path $dscResourcesFolderFilePath -ChildPath 'MSFT_ServiceResource'
|
||||
$serviceResourceModuleFilePath = Join-Path -Path $serviceResourceFolderFilePath -ChildPath 'MSFT_ServiceResource.psm1'
|
||||
Import-Module -Name $serviceResourceModuleFilePath
|
||||
|
||||
New-ServiceBinary `
|
||||
-ServiceName $script:testServiceName `
|
||||
-ServiceCodePath $script:testServiceNewCodePath `
|
||||
-ServiceDisplayName $script:testServiceNewDisplayName `
|
||||
-ServiceDescription $script:testServiceNewDescription `
|
||||
-ServiceDependsOn $script:testServiceNewDependsOn `
|
||||
-ServiceExecutablePath $script:testServiceExecutablePath
|
||||
# Configuration file paths
|
||||
$script:configurationAllExceptCredentialFilePath = Join-Path -Path $PSScriptRoot -ChildPath 'MSFT_ServiceResource_AllExceptCredential.config.ps1'
|
||||
$script:configurationCredentialOnlyFilePath = Join-Path -Path $PSScriptRoot -ChildPath 'MSFT_ServiceResource_CredentialOnly.config.ps1'
|
||||
|
||||
#region Integration Tests
|
||||
$configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:DscResourceName)_Add.config.ps1"
|
||||
. $configFile
|
||||
# Create test service binary to be the existing service
|
||||
$script:existingServiceProperties = @{
|
||||
Name = 'TestService'
|
||||
DisplayName = 'TestDisplayName'
|
||||
Description = 'Test service description'
|
||||
Dependencies = @( 'winrm' )
|
||||
Path = Join-Path -Path $TestDrive -ChildPath 'DscTestService.exe'
|
||||
}
|
||||
|
||||
Describe "$($script:DscResourceName) Add Service" {
|
||||
$existingServiceNewExecutableParameters = @{
|
||||
ServiceName = $script:existingServiceProperties.Name
|
||||
ServiceCodePath = Join-Path -Path $script:testsHelpersPath -ChildPath 'DscTestService.cs'
|
||||
ServiceDisplayName = $script:existingServiceProperties.DisplayName
|
||||
ServiceDescription = $script:existingServiceProperties.Description
|
||||
ServiceDependsOn = $script:existingServiceProperties.Dependencies -join ', '
|
||||
OutputPath = $script:existingServiceProperties.Path
|
||||
}
|
||||
|
||||
It 'Should compile and apply the MOF without throwing' {
|
||||
New-ServiceExecutable @existingServiceNewExecutableParameters
|
||||
|
||||
# Create test service binary to be the new service with the same name as the existing service
|
||||
$script:newServiceProperties = @{
|
||||
Name = $script:existingServiceProperties.Name
|
||||
DisplayName = 'NewTestDisplayName'
|
||||
Description = 'New test service description'
|
||||
Dependencies = @( 'spooler' )
|
||||
Path = Join-Path -Path $TestDrive -ChildPath 'NewDscTestService.exe'
|
||||
}
|
||||
|
||||
if (Test-IsNanoServer)
|
||||
{
|
||||
& "$($script:DscResourceName)_Add_Config" `
|
||||
-OutputPath $script:testEnvironment.WorkingFolder `
|
||||
-ServiceName $script:testServiceName `
|
||||
-ServicePath $script:testServiceExecutablePath `
|
||||
-ServiceDisplayName $script:testServiceDisplayName `
|
||||
-ServiceDescription $script:testServiceDescription `
|
||||
-ServiceDependsOn $script:testServiceDependsOn
|
||||
# Nano Server does not recognize 'spooler', so keep the dependencies value as 'winrm'
|
||||
$newServiceProperties['Dependencies'] = @( 'winrm' )
|
||||
}
|
||||
|
||||
Start-DscConfiguration -Path $script:testEnvironment.WorkingFolder `
|
||||
-ComputerName localhost -Wait -Verbose -Force
|
||||
} | Should Not Throw
|
||||
$newServiceNewExecutableParameters = @{
|
||||
ServiceName = $script:newServiceProperties.Name
|
||||
ServiceCodePath = Join-Path -Path $script:testHelpersPath -ChildPath 'DscTestServiceNew.cs'
|
||||
ServiceDisplayName = $script:newServiceProperties.DisplayName
|
||||
ServiceDescription = $script:newServiceProperties.Description
|
||||
ServiceDependsOn = $script:newServiceProperties.Dependencies -join ', '
|
||||
OutputPath = $script:newServiceProperties.Path
|
||||
}
|
||||
|
||||
New-ServiceExecutable @newServiceNewExecutableParameters
|
||||
|
||||
$script:testServiceNames = @( $script:existingServiceProperties.Name )
|
||||
$script:testServiceExecutables = @( $script:existingServiceProperties.Path, $script:newServiceProperties.Path )
|
||||
}
|
||||
|
||||
It 'Should be able to call Get-DscConfiguration without throwing' {
|
||||
{ Get-DscConfiguration -Verbose -ErrorAction Stop } | Should Not Throw
|
||||
AfterAll {
|
||||
# Remove any created services
|
||||
foreach ($testServiceName in $script:testServiceNames)
|
||||
{
|
||||
if (Test-ServiceExists -Name $testServiceName)
|
||||
{
|
||||
Remove-ServiceWithTimeout -Name $testServiceName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$script:service = Get-CimInstance -ClassName Win32_Service -Filter "Name='$($script:testServiceName)'"
|
||||
It 'Should return a service of type CimInstance' {
|
||||
$script:service | Should BeOfType 'Microsoft.Management.Infrastructure.CimInstance'
|
||||
Context 'Create a service' {
|
||||
Reset-DSC
|
||||
|
||||
$configurationName = 'TestCreateService'
|
||||
$resourceParameters = $script:existingServiceProperties
|
||||
|
||||
It 'Should compile and apply the MOF without throwing' {
|
||||
{
|
||||
. $script:configurationAllExceptCredentialFilePath -ConfigurationName $configurationName
|
||||
& $configurationName -OutputPath $TestDrive @resourceParameters
|
||||
Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force
|
||||
} | Should Not Throw
|
||||
}
|
||||
|
||||
$service = Get-Service -Name $resourceParameters.Name -ErrorAction 'SilentlyContinue'
|
||||
$serviceCimInstance = Get-CimInstance -ClassName 'Win32_Service' -Filter "Name='$($resourceParameters.Name)'" -ErrorAction 'SilentlyContinue'
|
||||
|
||||
It 'Should have created a new service with the specified name' {
|
||||
$service | Should Not Be $null
|
||||
$serviceCimInstance | Should Not Be $null
|
||||
|
||||
$service.Name | Should Be $resourceParameters.Name
|
||||
$serviceCimInstance.Name | Should Be $resourceParameters.Name
|
||||
}
|
||||
|
||||
It 'Should have created a new service with the specified path' {
|
||||
$serviceCimInstance.PathName | Should Be $resourceParameters.Path
|
||||
}
|
||||
|
||||
It 'Should have created a new service with the specified display name' {
|
||||
$service.DisplayName | Should Be $resourceParameters.DisplayName
|
||||
}
|
||||
|
||||
It 'Should have created a new service with the specified description' {
|
||||
$serviceCimInstance.Description | Should Be $resourceParameters.Description
|
||||
}
|
||||
|
||||
It 'Should have created a new service with the specified dependencies' {
|
||||
$differentDependencies = Compare-Object -ReferenceObject $resourceParameters.Dependencies -DifferenceObject $service.ServicesDependedOn.Name
|
||||
$differentDependencies | Should Be $null
|
||||
}
|
||||
|
||||
It 'Should have created a new service with the default state as Running' {
|
||||
$service.Status | Should Be 'Running'
|
||||
}
|
||||
|
||||
It 'Should have created a new service with the default startup type as Auto' {
|
||||
$serviceCimInstance.StartMode | Should Be 'Auto'
|
||||
}
|
||||
|
||||
It 'Should have created a new service with the default startup account name as LocalSystem' {
|
||||
$serviceCimInstance.StartName | Should Be 'LocalSystem'
|
||||
}
|
||||
|
||||
It 'Should have created a new service with the default desktop interaction setting as False' {
|
||||
$serviceCimInstance.DesktopInteract | Should Be $false
|
||||
}
|
||||
|
||||
It 'Should return true from Test-TargetResource with the same parameters' {
|
||||
MSFT_ServiceResource\Test-TargetResource @resourceParameters | Should Be $true
|
||||
}
|
||||
}
|
||||
|
||||
It 'Should have set the resource and all the parameters should match' {
|
||||
# Get the current service details
|
||||
$script:service.status | Should Be 'OK'
|
||||
$script:service.pathname | Should Be $script:testServiceExecutablePath
|
||||
$script:service.description | Should Be $script:testServiceDescription
|
||||
$script:service.displayname | Should Be $script:testServiceDisplayName
|
||||
$script:service.started | Should Be $true
|
||||
$script:service.state | Should Be 'Running'
|
||||
$script:service.desktopinteract | Should Be $true
|
||||
$script:service.startname | Should Be 'LocalSystem'
|
||||
$script:service.startmode | Should Be 'Auto'
|
||||
Context 'Edit the service path, display name, description, and dependencies' {
|
||||
Reset-DSC
|
||||
|
||||
$configurationName = 'TestCreateService'
|
||||
$resourceParameters = $script:newServiceProperties
|
||||
|
||||
It 'Should compile and apply the MOF without throwing' {
|
||||
{
|
||||
. $script:configurationAllExceptCredentialFilePath -ConfigurationName $configurationName
|
||||
& $configurationName -OutputPath $TestDrive @resourceParameters
|
||||
Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force
|
||||
} | Should Not Throw
|
||||
}
|
||||
|
||||
$service = Get-Service -Name $resourceParameters.Name -ErrorAction 'SilentlyContinue'
|
||||
$serviceCimInstance = Get-CimInstance -ClassName 'Win32_Service' -Filter "Name='$($resourceParameters.Name)'" -ErrorAction 'SilentlyContinue'
|
||||
|
||||
It 'Should not have removed service with specified name' {
|
||||
$service | Should Not Be $null
|
||||
$serviceCimInstance | Should Not Be $null
|
||||
|
||||
$service.Name | Should Be $resourceParameters.Name
|
||||
$serviceCimInstance.Name | Should Be $resourceParameters.Name
|
||||
}
|
||||
|
||||
It 'Should have edited service to have the specified path' {
|
||||
$serviceCimInstance.PathName | Should Be $resourceParameters.Path
|
||||
}
|
||||
|
||||
It 'Should have edited service to have the specified display name' {
|
||||
$service.DisplayName | Should Be $resourceParameters.DisplayName
|
||||
}
|
||||
|
||||
It 'Should have edited service to have the specified description' {
|
||||
$serviceCimInstance.Description | Should Be $resourceParameters.Description
|
||||
}
|
||||
|
||||
It 'Should have edited service to have the specified dependencies' {
|
||||
$differentDependencies = Compare-Object -ReferenceObject $resourceParameters.Dependencies -DifferenceObject $service.ServicesDependedOn.Name
|
||||
$differentDependencies | Should Be $null
|
||||
}
|
||||
|
||||
It 'Should not have changed the service state from Running' {
|
||||
$service.Status | Should Be 'Running'
|
||||
}
|
||||
|
||||
It 'Should not have changed the service startup type from Auto' {
|
||||
$serviceCimInstance.StartMode | Should Be 'Auto'
|
||||
}
|
||||
|
||||
It 'Should not have changed the service startup account name from LocalSystem' {
|
||||
$serviceCimInstance.StartName | Should Be 'LocalSystem'
|
||||
}
|
||||
|
||||
It 'Should not have changed the service desktop interaction setting from False' {
|
||||
$serviceCimInstance.DesktopInteract | Should Be $false
|
||||
}
|
||||
|
||||
It 'Should return true from Test-TargetResource with the same parameters' {
|
||||
MSFT_ServiceResource\Test-TargetResource @resourceParameters | Should Be $true
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Edit the service startup type and state' {
|
||||
Reset-DSC
|
||||
|
||||
$configurationName = 'TestCreateService'
|
||||
$resourceParameters = @{
|
||||
Name = $script:existingServiceProperties.Name
|
||||
Path = $script:newServiceProperties.Path
|
||||
StartupType = 'Manual'
|
||||
State = 'Stopped'
|
||||
}
|
||||
|
||||
It 'Should compile and apply the MOF without throwing' {
|
||||
{
|
||||
. $script:configurationAllExceptCredentialFilePath -ConfigurationName $configurationName
|
||||
& $configurationName -OutputPath $TestDrive @resourceParameters
|
||||
Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force
|
||||
} | Should Not Throw
|
||||
}
|
||||
|
||||
$service = Get-Service -Name $resourceParameters.Name -ErrorAction 'SilentlyContinue'
|
||||
$serviceCimInstance = Get-CimInstance -ClassName 'Win32_Service' -Filter "Name='$($resourceParameters.Name)'" -ErrorAction 'SilentlyContinue'
|
||||
|
||||
It 'Should not have removed service with specified name' {
|
||||
$service | Should Not Be $null
|
||||
$serviceCimInstance | Should Not Be $null
|
||||
|
||||
$service.Name | Should Be $resourceParameters.Name
|
||||
$serviceCimInstance.Name | Should Be $resourceParameters.Name
|
||||
}
|
||||
|
||||
It 'Should have edited the service to have the specified state' {
|
||||
$service.Status | Should Be $resourceParameters.State
|
||||
}
|
||||
|
||||
It 'Should have edited the service to have the specified startup type' {
|
||||
$serviceCimInstance.StartMode | Should Be $resourceParameters.StartupType
|
||||
}
|
||||
|
||||
It 'Should return true from Test-TargetResource with the same parameters' {
|
||||
MSFT_ServiceResource\Test-TargetResource @resourceParameters | Should Be $true
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Edit the service start name and start password with Credential' {
|
||||
Reset-DSC
|
||||
|
||||
$configData = @{
|
||||
AllNodes = @(
|
||||
@{
|
||||
NodeName = 'localhost'
|
||||
PSDscAllowPlainTextPassword = $true
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
$configurationName = 'TestCreateService'
|
||||
$resourceParameters = @{
|
||||
Name = 'TestService'
|
||||
Credential = Get-AppVeyorAdministratorCredential
|
||||
}
|
||||
|
||||
It 'Should compile and apply the MOF without throwing' {
|
||||
{
|
||||
. $script:configurationCredentialOnlyFilePath -ConfigurationName $configurationName
|
||||
& $configurationName -OutputPath $TestDrive -ConfigurationData $configData @resourceParameters
|
||||
Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force
|
||||
} | Should Not Throw
|
||||
}
|
||||
|
||||
$service = Get-Service -Name $resourceParameters.Name -ErrorAction 'SilentlyContinue'
|
||||
$serviceCimInstance = Get-CimInstance -ClassName 'Win32_Service' -Filter "Name='$($resourceParameters.Name)'" -ErrorAction 'SilentlyContinue'
|
||||
|
||||
It 'Should not have removed service with specified name' {
|
||||
$service | Should Not Be $null
|
||||
$serviceCimInstance | Should Not Be $null
|
||||
|
||||
$service.Name | Should Be $resourceParameters.Name
|
||||
$serviceCimInstance.Name | Should Be $resourceParameters.Name
|
||||
}
|
||||
|
||||
It 'Should have edited the service to have the specified startup account name' {
|
||||
$expectedStartName = $resourceParameters.Credential.UserName
|
||||
|
||||
if ($expectedStartName.StartsWith("$env:COMPUTERNAME\"))
|
||||
{
|
||||
$expectedStartName = $expectedStartName.TrimStart("$env:COMPUTERNAME\")
|
||||
}
|
||||
|
||||
$serviceCimInstance.StartName | Should Be ".\$expectedStartName"
|
||||
}
|
||||
|
||||
It 'Should return true from Test-TargetResource with the same parameters' {
|
||||
MSFT_ServiceResource\Test-TargetResource @resourceParameters | Should Be $true
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Edit the service start name and start password with BuiltInAccount' {
|
||||
Reset-DSC
|
||||
|
||||
$configurationName = 'TestCreateService'
|
||||
$resourceParameters = @{
|
||||
Name = 'TestService'
|
||||
Path = $script:newServiceProperties.Path
|
||||
BuiltInAccount = 'LocalService'
|
||||
}
|
||||
|
||||
It 'Should compile and apply the MOF without throwing' {
|
||||
{
|
||||
. $script:configurationAllExceptCredentialFilePath -ConfigurationName $configurationName
|
||||
& $configurationName -OutputPath $TestDrive @resourceParameters
|
||||
Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force
|
||||
} | Should Not Throw
|
||||
}
|
||||
|
||||
$service = Get-Service -Name $resourceParameters.Name -ErrorAction 'SilentlyContinue'
|
||||
$serviceCimInstance = Get-CimInstance -ClassName 'Win32_Service' -Filter "Name='$($resourceParameters.Name)'" -ErrorAction 'SilentlyContinue'
|
||||
|
||||
It 'Should not have removed service with specified name' {
|
||||
$service | Should Not Be $null
|
||||
$serviceCimInstance | Should Not Be $null
|
||||
|
||||
$service.Name | Should Be $resourceParameters.Name
|
||||
$serviceCimInstance.Name | Should Be $resourceParameters.Name
|
||||
}
|
||||
|
||||
It 'Should have edited the service to have the specified startup account name' {
|
||||
$serviceCimInstance.StartName | Should Be 'NT Authority\LocalService'
|
||||
}
|
||||
|
||||
It 'Should return true from Test-TargetResource with the same parameters' {
|
||||
MSFT_ServiceResource\Test-TargetResource @resourceParameters | Should Be $true
|
||||
}
|
||||
}
|
||||
|
||||
Context 'Remove the service' {
|
||||
Reset-DSC
|
||||
|
||||
$configurationName = 'TestCreateService'
|
||||
$resourceParameters = @{
|
||||
Name = $script:existingServiceProperties.Name
|
||||
Path = $script:existingServiceProperties.Path
|
||||
Ensure = 'Absent'
|
||||
}
|
||||
|
||||
It 'Should compile and apply the MOF without throwing' {
|
||||
{
|
||||
. $script:configurationAllExceptCredentialFilePath -ConfigurationName $configurationName
|
||||
& $configurationName -OutputPath $TestDrive @resourceParameters
|
||||
Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force
|
||||
} | Should Not Throw
|
||||
}
|
||||
|
||||
$service = Get-Service -Name $resourceParameters.Name -ErrorAction 'SilentlyContinue'
|
||||
$serviceCimInstance = Get-CimInstance -ClassName 'Win32_Service' -Filter "Name='$($resourceParameters.Name)'" -ErrorAction 'SilentlyContinue'
|
||||
|
||||
It 'Should have removed the service with specified name' {
|
||||
$service | Should Be $null
|
||||
$serviceCimInstance | Should Be $null
|
||||
}
|
||||
|
||||
It 'Should return true from Test-TargetResource with the same parameters' {
|
||||
MSFT_ServiceResource\Test-TargetResource @resourceParameters | Should Be $true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reset-DSC
|
||||
|
||||
$configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:DscResourceName)_Edit.config.ps1"
|
||||
. $configFile
|
||||
|
||||
Describe "$($script:DscResourceName) Edit Service" {
|
||||
|
||||
It 'Should compile and apply the MOF without throwing' {
|
||||
{
|
||||
& "$($script:DscResourceName)_Edit_Config" `
|
||||
-OutputPath $script:testEnvironment.WorkingFolder `
|
||||
-ServiceName $script:testServiceName `
|
||||
-ServicePath $script:testServiceNewExecutablePath `
|
||||
-ServiceDisplayName $script:testServiceNewDisplayName `
|
||||
-ServiceDescription $script:testServiceNewDescription `
|
||||
-ServiceDependsOn $script:testServiceNewDependsOn
|
||||
|
||||
Start-DscConfiguration -Path $script:testEnvironment.WorkingFolder `
|
||||
-ComputerName localhost -Wait -Verbose -Force
|
||||
} | Should Not Throw
|
||||
}
|
||||
|
||||
It 'Should be able to call Get-DscConfiguration without throwing' {
|
||||
{ Get-DscConfiguration -Verbose -ErrorAction Stop } | Should Not Throw
|
||||
}
|
||||
|
||||
# Get the current service details
|
||||
$script:service = Get-CimInstance -ClassName Win32_Service -Filter "Name='$($script:testServiceName)'"
|
||||
It 'Should return a service or type CimInstance' {
|
||||
$script:service | Should BeOfType 'Microsoft.Management.Infrastructure.CimInstance'
|
||||
}
|
||||
|
||||
It 'Should have set the resource and all the parameters should match' {
|
||||
# Get the current service details
|
||||
$script:service.status | Should Be 'OK'
|
||||
$script:service.pathname | Should Be $script:testServiceNewExecutablePath
|
||||
$script:service.description | Should Be $script:testServiceNewDescription
|
||||
$script:service.displayname | Should Be $script:testServiceNewDisplayName
|
||||
$script:service.started | Should Be $false
|
||||
$script:service.state | Should Be 'Stopped'
|
||||
$script:service.desktopinteract | Should Be $false
|
||||
$script:service.startname | Should Be 'NT Authority\LocalService'
|
||||
$script:service.startmode | Should Be 'Manual'
|
||||
}
|
||||
}
|
||||
|
||||
Reset-DSC
|
||||
|
||||
$configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:DscResourceName)_Remove.config.ps1"
|
||||
. $configFile
|
||||
|
||||
Describe "$($script:DscResourceName) Remove Service" {
|
||||
|
||||
It 'Should compile and apply the MOF without throwing' {
|
||||
{
|
||||
& "$($script:DscResourceName)_Remove_Config" `
|
||||
-OutputPath $script:testEnvironment.WorkingFolder `
|
||||
-ServiceName $script:testServiceName
|
||||
|
||||
Start-DscConfiguration -Path $script:testEnvironment.WorkingFolder `
|
||||
-ComputerName localhost -Wait -Verbose -Force
|
||||
} | Should not throw
|
||||
}
|
||||
|
||||
It 'Should be able to call Get-DscConfiguration without throwing' {
|
||||
{ Get-DscConfiguration -Verbose -ErrorAction Stop } | Should Not throw
|
||||
}
|
||||
|
||||
# Get the current service details
|
||||
$script:service = Get-CimInstance -ClassName Win32_Service -Filter "Name='$($script:testServiceName)'"
|
||||
|
||||
It 'Should return the service as null' {
|
||||
$script:service | Should BeNullOrEmpty
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
finally
|
||||
{
|
||||
# Clean up
|
||||
Remove-TestService `
|
||||
-ServiceName $script:testServiceName `
|
||||
-ServiceExecutablePath $script:testServiceExecutablePath
|
||||
|
||||
Exit-DscResourceTestEnvironment -TestEnvironment $script:testEnvironment
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$ConfigurationName
|
||||
)
|
||||
|
||||
Configuration $ConfigurationName
|
||||
{
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$Name,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$Path,
|
||||
|
||||
[ValidateSet('Present', 'Absent')]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$Ensure = 'Present',
|
||||
|
||||
[Parameter()]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$DisplayName = "$Name DisplayName",
|
||||
|
||||
[Parameter()]
|
||||
[String]
|
||||
$Description = 'TestDescription',
|
||||
|
||||
[Parameter()]
|
||||
[String[]]
|
||||
[AllowEmptyCollection()]
|
||||
$Dependencies = @(),
|
||||
|
||||
[Parameter()]
|
||||
[ValidateSet('LocalSystem', 'LocalService', 'NetworkService')]
|
||||
[String]
|
||||
$BuiltInAccount = 'LocalSystem',
|
||||
|
||||
[Parameter()]
|
||||
[Boolean]
|
||||
$DesktopInteract = $false,
|
||||
|
||||
[Parameter()]
|
||||
[ValidateSet('Automatic', 'Manual', 'Disabled')]
|
||||
[String]
|
||||
$StartupType = 'Automatic',
|
||||
|
||||
[Parameter()]
|
||||
[ValidateSet('Running', 'Stopped', 'Ignore')]
|
||||
[String]
|
||||
$State = 'Running',
|
||||
|
||||
[Parameter()]
|
||||
[UInt32]
|
||||
$StartupTimeout = 30000,
|
||||
|
||||
[Parameter()]
|
||||
[UInt32]
|
||||
$TerminateTimeout = 30000
|
||||
)
|
||||
|
||||
Import-DscResource -ModuleName 'PSDscResources'
|
||||
|
||||
Node localhost
|
||||
{
|
||||
Service Service1
|
||||
{
|
||||
Name = $Name
|
||||
Ensure = $Ensure
|
||||
Path = $Path
|
||||
StartupType = $StartupType
|
||||
BuiltInAccount = $BuiltInAccount
|
||||
DesktopInteract = $DesktopInteract
|
||||
State = $State
|
||||
DisplayName = $DisplayName
|
||||
Description = $Description
|
||||
Dependencies = $Dependencies
|
||||
StartupTimeout = $StartupTimeout
|
||||
TerminateTimeout = $TerminateTimeout
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$ConfigurationName
|
||||
)
|
||||
|
||||
Configuration $ConfigurationName
|
||||
{
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$Name,
|
||||
|
||||
[ValidateSet('Present', 'Absent')]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$Ensure = 'Present',
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[System.Management.Automation.PSCredential]
|
||||
$Credential
|
||||
)
|
||||
|
||||
Import-DscResource -ModuleName 'PSDscResources'
|
||||
|
||||
Node localhost
|
||||
{
|
||||
Service Service1
|
||||
{
|
||||
Name = $Name
|
||||
Ensure = $Ensure
|
||||
Credential = $Credential
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
Configuration MSFT_ServiceResource_Add_Config {
|
||||
param
|
||||
(
|
||||
$ServiceName,
|
||||
$ServicePath,
|
||||
$ServiceDisplayName,
|
||||
$ServiceDescription,
|
||||
$ServiceDependsOn
|
||||
)
|
||||
|
||||
Import-DscResource -ModuleName PSDscResources
|
||||
|
||||
node localhost {
|
||||
Service AddService {
|
||||
Name = $ServiceName
|
||||
Ensure = 'Present'
|
||||
Path = $ServicePath
|
||||
StartupType = 'Automatic'
|
||||
BuiltInAccount = 'LocalSystem'
|
||||
DesktopInteract = $true
|
||||
State = 'Running'
|
||||
DisplayName = $ServiceDisplayName
|
||||
Description = $ServiceDescription
|
||||
Dependencies = $ServiceDependsOn
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
Configuration MSFT_ServiceResource_Edit_Config {
|
||||
param
|
||||
(
|
||||
$ServiceName,
|
||||
$ServicePath,
|
||||
$ServiceDisplayName,
|
||||
$ServiceDescription,
|
||||
$ServiceDependsOn
|
||||
)
|
||||
|
||||
Import-DscResource -ModuleName PSDscResources
|
||||
|
||||
node localhost {
|
||||
Service EditService {
|
||||
Name = $ServiceName
|
||||
Ensure = 'Present'
|
||||
Path = $ServicePath
|
||||
StartupType = 'Manual'
|
||||
BuiltInAccount = 'LocalService'
|
||||
DesktopInteract = $false
|
||||
State = 'Stopped'
|
||||
DisplayName = $ServiceDisplayName
|
||||
Description = $ServiceDescription
|
||||
Dependencies = $ServiceDependsOn
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
Configuration MSFT_ServiceResource_Remove_Config {
|
||||
param
|
||||
(
|
||||
$ServiceName
|
||||
)
|
||||
|
||||
Import-DscResource -ModuleName PSDscResources
|
||||
|
||||
node localhost {
|
||||
Service RemoveService {
|
||||
Name = $ServiceName
|
||||
Ensure = 'Absent'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")]
|
||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')]
|
||||
param ()
|
||||
|
||||
$errorActionPreference = 'Stop'
|
||||
@@ -87,6 +87,7 @@ function Test-IsLocalMachine
|
||||
NOTE: This is likely overkill; consider removing it.
|
||||
#>
|
||||
$networkAdapters = @(Get-CimInstance Win32_NetworkAdapterConfiguration)
|
||||
|
||||
foreach ($networkAdapter in $networkAdapters)
|
||||
{
|
||||
if ($null -ne $networkAdapter.IPAddress)
|
||||
|
||||
@@ -1,153 +1,140 @@
|
||||
$errorActionPreference = 'Stop'
|
||||
Set-StrictMode -Version 'Latest'
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates a service binary file.
|
||||
Creates a service executable.
|
||||
|
||||
.PARAMETER ServiceName
|
||||
The name of the service to create the binary file for.
|
||||
The name of the service to create the executable for.
|
||||
|
||||
.PARAMETER ServiceCodePath
|
||||
The path to the code for the service to create the binary file for.
|
||||
The path to the code for the service to create the executable for.
|
||||
|
||||
.PARAMETER ServiceDisplayName
|
||||
The display name of the service to create the binary file for.
|
||||
The display name of the service to create the executable for.
|
||||
|
||||
.PARAMETER ServiceDescription
|
||||
The description of the service to create the binary file for.
|
||||
The description of the service to create the executable for.
|
||||
|
||||
.PARAMETER ServiceDependsOn
|
||||
Dependencies of the service to create the binary file for.
|
||||
The names of the dependencies of the service to create the executable for.
|
||||
|
||||
.PARAMETER ServiceExecutablePath
|
||||
The path to write the service executable to.
|
||||
.PARAMETER OutputPath
|
||||
The path to write the outputed service executable to.
|
||||
#>
|
||||
function New-ServiceBinary
|
||||
function New-ServiceExecutable
|
||||
{
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$ServiceName,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$ServiceCodePath,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$ServiceDisplayName,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$ServiceDescription,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[Parameter()]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$ServiceDependsOn,
|
||||
$ServiceDependsOn = "''",
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$ServiceExecutablePath
|
||||
$OutputPath
|
||||
)
|
||||
|
||||
if (Get-Service $ServiceName -ErrorAction Ignore)
|
||||
{
|
||||
Stop-Service $ServiceName -ErrorAction SilentlyContinue
|
||||
Remove-TestService -ServiceName $ServiceName -ServiceExecutablePath $ServiceExecutablePath
|
||||
}
|
||||
|
||||
$fileText = Get-Content $ServiceCodePath -Raw
|
||||
$fileText = Get-Content -Path $ServiceCodePath -Raw
|
||||
$fileText = $fileText.Replace('TestServiceReplacementName', $ServiceName)
|
||||
$fileText = $fileText.Replace('TestServiceReplacementDisplayName', $ServiceDisplayName)
|
||||
$fileText = $fileText.Replace('TestServiceReplacementDescription', $ServiceDescription)
|
||||
$fileText = $fileText.Replace('TestServiceReplacementDependsOn', $ServiceDependsOn)
|
||||
Add-Type $fileText `
|
||||
-OutputAssembly $ServiceExecutablePath `
|
||||
-OutputType WindowsApplication `
|
||||
-ReferencedAssemblies @('System.ServiceProcess', 'System.Configuration.Install')
|
||||
|
||||
$addTypeParameters = @{
|
||||
TypeDefinition = $fileText
|
||||
OutputAssembly = $OutputPath
|
||||
OutputType = 'WindowsApplication'
|
||||
ReferencedAssemblies = @( 'System.ServiceProcess', 'System.Configuration.Install' )
|
||||
}
|
||||
|
||||
$null = Add-Type @addTypeParameters
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Retrieves the path to the install utility.
|
||||
Deletes the service with the given name and waits 5 seconds maximum for the service to be
|
||||
deleted.
|
||||
|
||||
.PARAMETER Name
|
||||
The name of the service to delete.
|
||||
#>
|
||||
function Get-InstallUtilPath
|
||||
{
|
||||
[CmdletBinding()]
|
||||
param ()
|
||||
|
||||
if ($env:Processor_Architecture -ieq 'amd64')
|
||||
{
|
||||
$frameworkName = 'Framework64'
|
||||
}
|
||||
else
|
||||
{
|
||||
$frameworkName = 'Framework'
|
||||
}
|
||||
|
||||
return Join-Path -Path (Resolve-Path "$env:WinDir\Microsoft.Net\$frameworkName\v4*") `
|
||||
-ChildPath 'installUtil.exe'
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Removes a service.
|
||||
|
||||
.PARAMETER ServiceName
|
||||
The name of the service to remove.
|
||||
|
||||
.PARAMETER ServiceExecutablePath
|
||||
The path to the executable of the service to remove.
|
||||
#>
|
||||
function Remove-TestService
|
||||
{
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$ServiceName,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$ServiceExecutablePath
|
||||
)
|
||||
|
||||
if (Get-Service -Name $ServiceName -ErrorAction SilentlyContinue)
|
||||
{
|
||||
$installUtility = Get-InstallUtilPath
|
||||
& $installUtility /u $ServiceExecutablePath
|
||||
}
|
||||
|
||||
Remove-Item $ServiceExecutablePath -Force -ErrorAction SilentlyContinue
|
||||
Remove-Item *.InstallLog -Force -ErrorAction SilentlyContinue
|
||||
Remove-Item $ServiceName -Force -Recurse -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
function Get-InvalidArgumentRecord
|
||||
function Remove-ServiceWithTimeout
|
||||
{
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[System.String]
|
||||
$ErrorId,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[System.String]
|
||||
$ErrorMessage
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String]
|
||||
$Name
|
||||
)
|
||||
|
||||
$exception = New-Object -TypeName System.InvalidOperationException `
|
||||
-ArgumentList $ErrorMessage
|
||||
$errorCategory = [System.Management.Automation.ErrorCategory]::InvalidOperation
|
||||
$errorRecord = New-Object -TypeName System.Management.Automation.ErrorRecord `
|
||||
-ArgumentList $exception, $ErrorId, $errorCategory, $null
|
||||
return $errorRecord
|
||||
Stop-Service -Name $Name
|
||||
|
||||
& 'sc.exe' 'delete' $Name
|
||||
|
||||
$serviceDeleted = $false
|
||||
$start = [DateTime]::Now
|
||||
|
||||
while (-not $serviceDeleted -and ([DateTime]::Now - $start).TotalMilliseconds -lt 5000)
|
||||
{
|
||||
$service = Get-Service -Name $Name -ErrorAction 'SilentlyContinue'
|
||||
|
||||
if ($null -eq $service)
|
||||
{
|
||||
$serviceDeleted = $true
|
||||
}
|
||||
else
|
||||
{
|
||||
Start-Sleep -Seconds 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Export-ModuleMember -Function `
|
||||
New-ServiceBinary, `
|
||||
New-TestService, `
|
||||
Remove-TestService, `
|
||||
Get-InvalidArgumentRecord
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Tests if the service with the specified name exists.
|
||||
|
||||
.PARAMETER Name
|
||||
The name of the service.
|
||||
#>
|
||||
function Test-ServiceExists
|
||||
{
|
||||
[OutputType([Boolean])]
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$Name
|
||||
)
|
||||
|
||||
$service = Get-Service -Name $Name -ErrorAction 'SilentlyContinue'
|
||||
return $null -ne $service
|
||||
}
|
||||
|
||||
Export-ModuleMember -Function @( 'New-ServiceExecutable', 'Remove-ServiceWithTimeout', 'Test-ServiceExists' )
|
||||
|
||||
+2356
-1822
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user