Tests/TestHelpers/MSFT_ServiceResource.TestHelper.psm1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
$errorActionPreference = 'Stop'
Set-StrictMode -Version 'Latest'

<#
    .SYNOPSIS
        Creates a service executable.
 
    .PARAMETER ServiceName
        The name of the service to create the executable for.
 
    .PARAMETER ServiceCodePath
        The path to the code for the service to create the executable for.
 
    .PARAMETER ServiceDisplayName
        The display name of the service to create the executable for.
 
    .PARAMETER ServiceDescription
        The description of the service to create the executable for.
 
    .PARAMETER ServiceDependsOn
        The names of the dependencies of the service to create the executable for.
 
    .PARAMETER OutputPath
        The path to write the outputed service executable to.
#>

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()]
        [ValidateNotNullOrEmpty()]
        [String]
        $ServiceDependsOn = "''",

        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [String]
        $OutputPath
    )

    $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)

    $addTypeParameters = @{
        TypeDefinition = $fileText
        OutputAssembly = $OutputPath
        OutputType = 'WindowsApplication'
        ReferencedAssemblies = @( 'System.ServiceProcess', 'System.Configuration.Install' )
    }

    $null = Add-Type @addTypeParameters
}

<#
    .SYNOPSIS
        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 Remove-ServiceWithTimeout
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullorEmpty()]
        [String]
        $Name
    )

    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
        }
    }
}

<#
    .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' )