Tests/Integration/AuditPolicyResourceHelper.Integration.Tests.ps1

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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#requires -RunAsAdministrator

# Get the root path of the resourse
[String] $script:moduleRoot = Split-Path -Parent ( Split-Path -Parent $PSScriptRoot )

Import-Module -Name (Join-Path -Path $moduleRoot `
                               -ChildPath 'DSCResources\AuditPolicyResourceHelper\AuditPolicyResourceHelper.psm1' ) `
                               -Force
#region Generate data

<#
    The auditpol utility outputs the list of categories and subcategories in a couple of different
    ways. Using the /list flag only returns the categories without the associated audit setting,
    so it is easier to filter later on.
#>


$script:subcategories = auditpol /get /category:* /R | ConvertFrom-Csv

#endregion

Describe 'Prerequisites' {

    # There are several dependencies for both Pester and AuditPolicyDsc that need to be validated.
    It "Should be running as admin" {
        # The tests need to run as admin to have access to the auditpol data
        ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
        [Security.Principal.WindowsBuiltInRole] "Administrator") | Should Be $true
    }

    It "Should find auditpol.exe in System32" {
        # If the auditpol is not located on the system, the entire module will fail
        Test-Path "$env:SystemRoot\system32\auditpol.exe" | Should Be $true
    }
}

Describe 'auditpol.exe output' {

    # Verify the raw auditpol output format has not changed across different OS versions and types.
    It 'Should get auditpol default return with no parameters' {
        ( auditpol.exe )[0] | Should BeExactly 'Usage: AuditPol command [<sub-command><options>]'
    }

    It 'Should get CSV format with the /r switch' {
        ( auditpol.exe /get /subcategory:logon /r )[0] |
        Should BeExactly "Machine Name,Policy Target,Subcategory,Subcategory GUID,Inclusion Setting,Exclusion Setting"
    }

    foreach ( $subcategory in $script:subcategories )
    {
        Context "Subcategory: $($subcategory.subcategory)" {

            $auditpolSubcategory = auditpol.exe /get /subcategory:$($subcategory.subcategory) /r | ConvertFrom-Csv

            It 'Should return the subcategory name' {
                $auditpolSubcategory.subcategory | Should Be $subcategory.subcategory
            }
            It 'Should return the subcategory GUID' {
                $auditpolSubcategory.'subcategory GUID' | Should Be $subcategory.'subcategory GUID'
            }
            It 'Should return the Inclusion Setting' {
                $auditpolSubcategory.'Inclusion Setting' | Should Be $subcategory.'Inclusion Setting'
            }
        }
    }
}

Describe "Function Invoke-Auditpol" {

    InModuleScope AuditPolicyResourceHelper {

        Context 'Subcategory and Option' {

            # These tests verify that an object is returned from Invoke-Auditpol
            It 'Should return an object when a single word subcategory is passed in' {
                $subcategory = Invoke-Auditpol -Command "Get" -SubCommand "Subcategory:Logoff"
                $subcategory.Subcategory         | Should Be 'Logoff'
                $subcategory.'Subcategory GUID'  | Should Not BeNullOrEmpty
                $subcategory.'Inclusion Setting' | Should Not BeNullOrEmpty
            }

            It 'Should return an object when a multi-word subcategory is passed in' {
                $subcategory = Invoke-Auditpol -Command "Get" -SubCommand "Subcategory:""Credential Validation"""
                $subcategory.Subcategory | Should Be 'Credential Validation'
                $subcategory.'Subcategory GUID'  | Should Not BeNullOrEmpty
                $subcategory.'Inclusion Setting' | Should Not BeNullOrEmpty
            }

            It 'Should return an object when an option is passed in' {
                $option = Invoke-Auditpol -Command "Get" -SubCommand "option:CrashOnAuditFail"
                $option.Subcategory | Should Be 'option:CrashOnAuditFail'
                $option.'Subcategory GUID'  | Should BeNullOrEmpty
                $option.'Inclusion Setting' | Should Not BeNullOrEmpty
            }
        }

        Context 'Backup' {

            $script:path = ([system.IO.Path]::GetTempFileName()).Replace('tmp','csv')

            It 'Should be able to call Invoke-Audtipol with backup and not throw' {
                {$script:auditpolBackupReturn = Invoke-AuditPol -Command 'Backup' `
                                                                -SubCommand "file:$script:path"} |
                    Should Not Throw
            }

            It 'Should not return anything when a backup is requested' {
                $script:auditpolBackupReturn | Should BeNullOrEmpty
            }

            It 'Should produce a valid CSV in a temp file when the backup switch is used' {
                (Get-Content -Path $script:path)[0] |
                    Should BeExactly "Machine Name,Policy Target,Subcategory,Subcategory GUID,Inclusion Setting,Exclusion Setting,Setting Value"
            }
        }

        Context 'Restore' {

            It 'Should be able to call Invoke-Audtipol with backup and not throw' {
                {$script:auditpolRestoreReturn = Invoke-AuditPol -Command 'Restore' `
                                                                 -SubCommand "file:$script:path"} |
                    Should Not Throw
            }

            It 'Should not return anything when a restore is requested' {
                $script:auditpolRestoreReturn | Should BeNullOrEmpty
            }
        }
    }
}

Describe 'Test-ValidSubcategory' {

    InModuleScope AuditPolicyResourceHelper {

        Context 'Invalid Input' {

            It 'Should not throw an exception' {
                { $script:testValidSubcategoryResult = Test-ValidSubcategory -Name 'Invalid' } |
                    Should Not Throw
            }

            It 'Should return false when an invalid Subcategory is passed ' {
                $script:testValidSubcategoryResult | Should Be $false
            }
        }

        Context 'Valid Input' {

            It 'Should not throw an exception' {
                { $script:testValidSubcategoryResult = Test-ValidSubcategory -Name 'logon' } |
                    Should Not Throw
            }

            It 'Should return true when a valid Subcategory is passed ' {
                $script:testValidSubcategoryResult | Should Be $true
            }
        }
    }
}