functions/flowcontrol/Test-PSFPowerShell.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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
function Test-PSFPowerShell
{
<#
    .SYNOPSIS
        Tests for conditions in the PowerShell environment.
     
    .DESCRIPTION
        This helper command can evaluate various runtime conditions, such as:
        - PowerShell Version
        - PowerShell Edition
        - Operating System
        - Elevation
        This makes it easier to do conditional code.
        It also makes it easier to simulate code-paths during pester tests, by mocking this command.
     
    .PARAMETER PSMinVersion
        PowerShell must be running under at least this version.
     
    .PARAMETER PSMaxVersion
        PowerShell most not be runnign on a version higher than this.
     
    .PARAMETER Edition
        PowerShell must be running in the specifioed edition (Core or Desktop)
     
    .PARAMETER OperatingSystem
        PowerShell must be running on the specified OS.
     
    .PARAMETER Elevated
        PowerShell must be running with elevation.
         
        Note:
        This test is only supported on Windows.
        On other OS it will automatically succede and assume root privileges.
     
    .PARAMETER ComputerName
        The computer on which to test local PowerShell conditions.
        If this parameter is not specified, it tests the current PowerShell process and hosting OS.
        Accepts established PowerShell sessions.
     
    .PARAMETER Credential
        The credentials to use when connecting to a remote computer.
     
    .EXAMPLE
        PS C:\> Test-PSFPowerShell -PSMinVersion 5.0
     
        Will return $false, unless the executing powershell version is at least 5.0
     
    .EXAMPLE
        PS C:\> Test-PSFPowerShell -Edition Core
     
        Will return $true, if the current powershell session is a PowerShell core session.
     
    .EXAMPLE
        PS C:\> Test-PSFPowerShell -Elevated
     
        Will return $false if on windows and not running as admin.
        Will return $true otherwise.
     
    .EXAMPLE
        PS C:\> Test-PSFPowerShell -PSMinVersion 6.1 -OperatingSystem Windows
     
        Will return $false unless executed on a PowerShell 6.1 console running on windows.
#>

    [OutputType([System.Boolean])]
    [CmdletBinding(HelpUri = 'https://psframework.org/documentation/commands/PSFramework/Test-PSFPowerShell')]
    param (
        [Version]
        $PSMinVersion,
        
        [Version]
        $PSMaxVersion,
        
        [PSFramework.FlowControl.PSEdition]
        $Edition,
        
        [PSFramework.FlowControl.OperatingSystem]
        [Alias('OS')]
        $OperatingSystem,
        
        [switch]
        $Elevated,
        
        [PSFComputer]
        $ComputerName,
        
        [PSCredential]
        $Credential
    )
    
    begin
    {
        $parameter = $PSBoundParameters | ConvertTo-PSFHashtable -Include ComputerName, Credential
    }
    process
    {
        #region Local execution for performance reasons separate
        if (-not $PSBoundParameters.ContainsKey('ComputerName'))
        {
            #region PS Version Test
            if ($PSMinVersion -and ($PSMinVersion -ge $PSVersionTable.PSVersion))
            {
                return $false
            }
            if ($PSMaxVersion -and ($PSMaxVersion -le $PSVersionTable.PSVersion))
            {
                return $false
            }
            #endregion PS Version Test
            
            #region PS Edition Test
            if ($Edition -like "Desktop")
            {
                if ($PSVersionTable.PSEdition -eq "Core")
                {
                    return $false
                }
            }
            if ($Edition -like "Core")
            {
                if ($PSVersionTable.PSEdition -ne "Core")
                {
                    return $false
                }
            }
            #endregion PS Edition Test
            
            #region OS Test
            if ($OperatingSystem)
            {
                switch ($OperatingSystem)
                {
                    "MacOS"
                    {
                        if ($PSVersionTable.PSVersion.Major -lt 6) { return $false }
                        if (-not $IsMacOS) { return $false }
                    }
                    "Linux"
                    {
                        if ($PSVersionTable.PSVersion.Major -lt 6) { return $false }
                        if (-not $IsLinux) { return $false }
                    }
                    "Windows"
                    {
                        if (($PSVersionTable.PSVersion.Major -ge 6) -and (-not $IsWindows))
                        {
                            return $false
                        }
                    }
                }
            }
            #endregion OS Test
            
            #region Elevation
            if ($Elevated)
            {
                if (($PSVersionTable.PSVersion.Major -lt 6) -or ($IsWindows))
                {
                    $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
                    $principal = New-Object Security.Principal.WindowsPrincipal $identity
                    if (-not $principal.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator))
                    {
                        return $false
                    }
                }
            }
            #endregion Elevation
            
            return $true
        }
        #endregion Local execution for performance reasons separate
        
        Invoke-PSFCommand @parameter -ScriptBlock {
            #region PS Version Test
            if ($PSMinVersion -and ($PSMinVersion -ge $PSVersionTable.PSVersion))
            {
                return $false
            }
            if ($PSMaxVersion -and ($PSMaxVersion -le $PSVersionTable.PSVersion))
            {
                return $false
            }
            #endregion PS Version Test
            
            #region PS Edition Test
            if ($Edition -like "Desktop")
            {
                if ($PSVersionTable.PSEdition -eq "Core")
                {
                    return $false
                }
            }
            if ($Edition -like "Core")
            {
                if ($PSVersionTable.PSEdition -ne "Core")
                {
                    return $false
                }
            }
            #endregion PS Edition Test
            
            #region OS Test
            if ($OperatingSystem)
            {
                switch ($OperatingSystem)
                {
                    "MacOS"
                    {
                        if ($PSVersionTable.PSVersion.Major -lt 6) { return $false }
                        if (-not $IsMacOS) { return $false }
                    }
                    "Linux"
                    {
                        if ($PSVersionTable.PSVersion.Major -lt 6) { return $false }
                        if (-not $IsLinux) { return $false }
                    }
                    "Windows"
                    {
                        if (($PSVersionTable.PSVersion.Major -ge 6) -and (-not $IsWindows))
                        {
                            return $false
                        }
                    }
                }
            }
            #endregion OS Test
            
            #region Elevation
            if ($Elevated)
            {
                if (($PSVersionTable.PSVersion.Major -lt 6) -or ($IsWindows))
                {
                    $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
                    $principal = New-Object Security.Principal.WindowsPrincipal $identity
                    if (-not $principal.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator))
                    {
                        return $false
                    }
                }
            }
            #endregion Elevation
            
            return $true
        }
    }
}