mirror of
https://github.com/PowerShell/PSDscResources
synced 2026-06-21 13:45:29 +00:00
adding Service resource
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
|
||||
[ClassVersion("1.0.0"),FriendlyName("Service")]
|
||||
class MSFT_ServiceResource : OMI_BaseResource
|
||||
{
|
||||
[Key,Description("Indicates the service name. Note that sometimes this is different from the display name. You can get a list of the services and their current state with the Get-Service cmdlet.")] String Name;
|
||||
[Write,Description("Ensures that the service is present or absent. Defaults to Present."),ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] String Ensure;
|
||||
[Write,Description("The path to the service executable file.")] String Path;
|
||||
[Write,Description("Indicates the startup type for the service."),ValueMap{"Automatic", "Manual", "Disabled"},Values{"Automatic", "Manual", "Disabled"}] String StartupType;
|
||||
[Write,Description("Indicates the sign-in account to use for the service."),ValueMap{"LocalSystem", "LocalService", "NetworkService"},Values{"LocalSystem", "LocalService", "NetworkService"}] String BuiltInAccount;
|
||||
[Write,Description("The credential to run the service under."),EmbeddedInstance("MSFT_Credential")] String Credential;
|
||||
[Write,Description("The service can create or communicate with a window on the desktop. Must be false for services not running as LocalSystem. Defaults to False.")] Boolean DesktopInteract;
|
||||
[Write,Description("Indicates the state you want to ensure for the service. Defaults to Running."),ValueMap{"Running", "Stopped", "Ignore"},Values{"Running", "Stopped", "Ignore"}] String State;
|
||||
[Write,Description("The display name of the service.")] String DisplayName;
|
||||
[Write,Description("The description of the service.")] String Description;
|
||||
[Write,Description("An array of strings indicating the names of the dependencies of the service.")] String Dependencies[];
|
||||
[Write,Description("The time to wait for the service to start in milliseconds. Defaults to 30000.")] uint32 StartupTimeout;
|
||||
[Write,Description("The time to wait for the service to stop in milliseconds. Defaults to 30000.")] uint32 TerminateTimeout;
|
||||
};
|
||||
Binary file not shown.
@@ -0,0 +1,49 @@
|
||||
# Localized resources for MSFT_ServiceResource
|
||||
|
||||
ConvertFrom-StringData @'
|
||||
ServiceNotFound = Service '{0}' not found.
|
||||
CannotStartAndDisable = Cannot start and disable a service.
|
||||
CannotStopServiceSetToStartAutomatically = Cannot stop a service and set it to start automatically.
|
||||
ServiceAlreadyStarted = Service '{0}' already started, no action required.
|
||||
ServiceStarted = Service '{0}' started.
|
||||
ServiceStopped = Service '{0}' stopped.
|
||||
ErrorStartingService = Failure starting service '{0}'. Please check the path '{1}' provided for the service. Message: '{2}'
|
||||
OnlyOneParameterCanBeSpecified = Only one of the following parameters can be specified: '{0}', '{1}'.
|
||||
StartServiceWhatIf = Start Service
|
||||
StopServiceWhatIf = Stop Service
|
||||
ServiceAlreadyStopped = Service '{0}' already stopped, no action required.
|
||||
ErrorStoppingService = Failure stopping service '{0}'. Message: '{1}'
|
||||
ErrorRetrievingServiceInformation = Failure retrieving information for service '{0}'. Message: '{1}'
|
||||
ErrorSettingServiceCredential = Failure setting credentials for service '{0}'. Message: '{1}'
|
||||
SetCredentialWhatIf = Set Credential
|
||||
SetStartupTypeWhatIf = Set Start Type
|
||||
ErrorSettingServiceStartupType = Failure setting start type for service '{0}'. Message: '{1}'
|
||||
TestBinaryPathMismatch = Binary path for service '{0}' is '{1}'. It does not match '{2}'.
|
||||
TestUserNameMismatch = User name for service '{0}' is '{1}'. It does not match '{2}'.
|
||||
TestStartupTypeMismatch = Startup type for service '{0}' is '{1}'. It does not match '{2}'.
|
||||
TestDesktopInteractMismatch = Desktop interact for service '{0}' is '{1}'. It does not match '{2}'.
|
||||
TestStateMismatch = State of service '{0}' is '{1}'. It does not match '{2}'.
|
||||
MethodFailed = The '{0}' method of '{1}' failed with error code: '{2}'.
|
||||
ErrorChangingProperty = Failed to change '{0}' property. Message: '{1}'
|
||||
ErrorSettingLogOnAsServiceRightsForUser = Error granting '{0}' the right to log on as a service. Message: '{1}'.
|
||||
CannotOpenPolicyErrorMessage = Cannot open policy manager.
|
||||
UserNameTooLongErrorMessage = User name is too long.
|
||||
CannotLookupNamesErrorMessage = Failed to lookup user name.
|
||||
CannotOpenAccountErrorMessage = Failed to open policy for user.
|
||||
CannotCreateAccountAccessErrorMessage = Failed to create policy for user.
|
||||
CannotGetAccountAccessErrorMessage = Failed to get user policy rights.
|
||||
CannotSetAccountAccessErrorMessage = Failed to set user policy rights.
|
||||
BinaryPathNotSpecified = Specify the path to the executable when trying to create a new service.
|
||||
ServiceAlreadyExists = The service '{0}' to create already exists.
|
||||
ServiceExistsSamePath = The service '{0}' to create already exists with path '{1}'.
|
||||
ServiceDoesNotExistPathMissingError = The service '{0}' does not exist. Specify the path to the executable to create a new service.
|
||||
ErrorDeletingService = Error in deleting service '{0}'.
|
||||
ServiceDeletedSuccessfully = Service '{0}' Deleted Successfully.
|
||||
TryDeleteAgain = Wait for 2 milliseconds for a service to get deleted.
|
||||
WritePropertiesIgnored = Service '{0}' already exists. Write properties such as Status, DisplayName, Description, Dependencies will be ignored for existing services.
|
||||
ErrorCreatingService = Error creating service '{0}'; Exception Message: '{1}'
|
||||
ServiceNeedsRestartMessage = Service '{0}' needs to be restarted.
|
||||
ServiceExecutablePathChangeNotSupported = Changing the path to an existing service executable is not yet supported.
|
||||
NotCheckingOtherValuesEnsureAbsent = Not checking other values since Ensure is set to Absent.
|
||||
ServiceDoesNotExist = Service does not exist.
|
||||
'@
|
||||
@@ -0,0 +1,60 @@
|
||||
Configuration Sample_Service_CreateService
|
||||
{
|
||||
|
||||
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
|
||||
Ensure = $Ensure
|
||||
Path = $Path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Sample_Service_CreateService -Name 'Sample Service' -Ensure 'Present' -Path 'C:\DSC\TestService.exe'
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
Configuration Sample_Service_DeleteService
|
||||
{
|
||||
|
||||
param
|
||||
(
|
||||
[System.String[]]
|
||||
$nodeName = 'localhost',
|
||||
|
||||
[System.String]
|
||||
$Name,
|
||||
|
||||
[System.String]
|
||||
[ValidateSet('Automatic', 'Manual', 'Disabled')]
|
||||
$StartupType,
|
||||
|
||||
[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
|
||||
{
|
||||
Service service
|
||||
{
|
||||
Name = $Name
|
||||
Ensure = $Ensure
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Sample_Service_DeleteService -Name 'Sample Service' -Ensure 'Absent'
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
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,185 @@
|
||||
|
||||
$script:DscResourceName = 'MSFT_ServiceResource'
|
||||
|
||||
Import-Module -Name (Join-Path -Path (Split-Path $PSScriptRoot -Parent) `
|
||||
-ChildPath 'CommonTestHelper.psm1') `
|
||||
-Force
|
||||
|
||||
$script:testEnvironment = Enter-DscResourceTestEnvironment `
|
||||
-DscResourceModuleName 'PSDscResources' `
|
||||
-DscResourceName 'MSFT_ServiceResource' `
|
||||
-TestType 'Integration'
|
||||
|
||||
try
|
||||
{
|
||||
$script:testServiceName = 'DscTestService'
|
||||
$script:testServiceCodePath = Join-Path -Path (Split-Path $PSScriptRoot -Parent) -ChildPath '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 $PSScriptRoot -Parent) -ChildPath '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' }
|
||||
|
||||
Import-Module -Name (Join-Path -Path (Split-Path $PSScriptRoot -Parent) `
|
||||
-ChildPath 'MSFT_ServiceResource.TestHelper.psm1') `
|
||||
-Force
|
||||
|
||||
Stop-Service $script:testServiceName -ErrorAction SilentlyContinue
|
||||
|
||||
# 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
|
||||
|
||||
New-ServiceBinary `
|
||||
-ServiceName $script:testServiceName `
|
||||
-ServiceCodePath $script:testServiceNewCodePath `
|
||||
-ServiceDisplayName $script:testServiceNewDisplayName `
|
||||
-ServiceDescription $script:testServiceNewDescription `
|
||||
-ServiceDependsOn $script:testServiceNewDependsOn `
|
||||
-ServiceExecutablePath $script:testServiceExecutablePath
|
||||
|
||||
#region Integration Tests
|
||||
$configFile = Join-Path -Path $PSScriptRoot -ChildPath "$($script:DscResourceName)_Add.config.ps1"
|
||||
. $configFile
|
||||
|
||||
Describe "$($script:DscResourceName) Add Service" {
|
||||
|
||||
It 'Should compile and apply the MOF without throwing' {
|
||||
{
|
||||
& "$($script:DscResourceName)_Add_Config" `
|
||||
-OutputPath $script:testEnvironment.WorkingFolder `
|
||||
-ServiceName $script:testServiceName `
|
||||
-ServicePath $script:testServiceExecutablePath `
|
||||
-ServiceDisplayName $script:testServiceDisplayName `
|
||||
-ServiceDescription $script:testServiceDescription `
|
||||
-ServiceDependsOn $script:testServiceDependsOn
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
$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'
|
||||
}
|
||||
|
||||
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'
|
||||
}
|
||||
}
|
||||
|
||||
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,27 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
Configuration MSFT_ServiceResource_Remove_Config {
|
||||
param
|
||||
(
|
||||
$ServiceName
|
||||
)
|
||||
|
||||
Import-DscResource -ModuleName PSDscResources
|
||||
|
||||
node localhost {
|
||||
Service RemoveService {
|
||||
Name = $ServiceName
|
||||
Ensure = 'Absent'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates a service binary file.
|
||||
|
||||
.PARAMETER ServiceName
|
||||
The name of the service to create the binary file for.
|
||||
|
||||
.PARAMETER ServiceCodePath
|
||||
The path to the code for the service to create the binary file for.
|
||||
|
||||
.PARAMETER ServiceDisplayName
|
||||
The display name of the service to create the binary file for.
|
||||
|
||||
.PARAMETER ServiceDescription
|
||||
The description of the service to create the binary file for.
|
||||
|
||||
.PARAMETER ServiceDependsOn
|
||||
Dependencies of the service to create the binary file for.
|
||||
|
||||
.PARAMETER ServiceExecutablePath
|
||||
The path to write the service executable to.
|
||||
#>
|
||||
function New-ServiceBinary
|
||||
{
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$ServiceName,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$ServiceCodePath,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$ServiceDisplayName,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$ServiceDescription,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$ServiceDependsOn,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$ServiceExecutablePath
|
||||
)
|
||||
|
||||
if (Get-Service $ServiceName -ErrorAction Ignore)
|
||||
{
|
||||
Stop-Service $ServiceName -ErrorAction SilentlyContinue
|
||||
Remove-TestService -ServiceName $ServiceName -ServiceExecutablePath $ServiceExecutablePath
|
||||
}
|
||||
|
||||
$fileText = Get-Content $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')
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates a new service for testing.
|
||||
|
||||
.PARAMETER ServiceName
|
||||
The name of the service to create.
|
||||
|
||||
.PARAMETER ServiceCodePath
|
||||
The path to the code for the service to create.
|
||||
|
||||
.PARAMETER ServiceDisplayName
|
||||
The display name of the service to create.
|
||||
|
||||
.PARAMETER ServiceDescription
|
||||
The description of the service to create.
|
||||
|
||||
.PARAMETER ServiceDependsOn
|
||||
Dependencies of the service to create.
|
||||
|
||||
.PARAMETER ServiceExecutablePath
|
||||
The path to write the service executable to.
|
||||
#>
|
||||
function New-TestService
|
||||
{
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$ServiceName,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$ServiceCodePath,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$ServiceDisplayName,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$ServiceDescription,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$ServiceDependsOn,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[String]
|
||||
$ServiceExecutablePath
|
||||
)
|
||||
|
||||
New-ServiceBinary `
|
||||
-ServiceName $ServiceName `
|
||||
-ServiceCodePath $ServiceCodePath `
|
||||
-ServiceDisplayName $ServiceDisplayName `
|
||||
-ServiceDescription $ServiceDescription `
|
||||
-ServiceDependsOn $ServiceDependsOn `
|
||||
-ServiceExecutablePath $ServiceExecutablePath
|
||||
|
||||
if (-not (Test-Path $ServiceExecutablePath))
|
||||
{
|
||||
throw 'Failed to create service executable file.'
|
||||
}
|
||||
|
||||
$configurationName = 'TestServiceConfig'
|
||||
$configurationPath = Join-Path -Path (Get-Location) -ChildPath $ServiceName
|
||||
|
||||
Configuration $configurationName
|
||||
{
|
||||
Import-DscResource -ModuleName PSDscResources
|
||||
|
||||
Service Service1
|
||||
{
|
||||
Name = $ServiceName
|
||||
Path = $ServiceExecutablePath
|
||||
DisplayName = $ServiceDisplayName
|
||||
Description = $ServiceDescription
|
||||
Dependencies = $ServiceDependsOn
|
||||
StartupType = 'Manual'
|
||||
BuiltInAccount = 'LocalSystem'
|
||||
State = 'Stopped'
|
||||
Ensure = 'Present'
|
||||
}
|
||||
}
|
||||
|
||||
& $configurationName -OutputPath $configurationPath
|
||||
|
||||
Start-DscConfiguration -Path $configurationPath -Wait -Force -Verbose
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Retrieves the path to the install utility.
|
||||
#>
|
||||
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
|
||||
{
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[System.String]
|
||||
$ErrorId,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[System.String]
|
||||
$ErrorMessage
|
||||
)
|
||||
|
||||
$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
|
||||
}
|
||||
|
||||
Export-ModuleMember -Function `
|
||||
New-ServiceBinary, `
|
||||
New-TestService, `
|
||||
Remove-TestService, `
|
||||
Get-InvalidArgumentRecord
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user