Skip to content

Commit f094f2f

Browse files
committed
Remove/simplify conditional checks which would would always be met with a minimum version of 5.1 (no longer supporting v3 or v4)
1 parent 3d8013a commit f094f2f

24 files changed

+210
-315
lines changed

Engine/PSScriptAnalyzer.psm1

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,10 @@ if ($PSVersionTable.PSVersion.Major -ge 6) {
1919
if ($PSVersionTable.PSVersion -lt $minimumPowerShellCoreVersion) {
2020
throw "Minimum supported version of PSScriptAnalyzer for PowerShell Core is $minimumPowerShellCoreVersion but current version is '$($PSVersionTable.PSVersion)'. Please update PowerShell Core."
2121
}
22-
}
23-
elseif ($PSVersionTable.PSVersion.Major -eq 5) {
22+
} else {
2423
# Without this, PSSA tries to load this from $PSHome
2524
Add-Type -Path "$PSScriptRoot/Newtonsoft.Json.dll"
2625
}
27-
elseif ($PSVersionTable.PSVersion.Major -le 4) {
28-
$binaryModuleRoot = Join-Path -Path $PSModuleRoot -ChildPath "PSv$($PSVersionTable.PSVersion.Major)"
29-
# Without this, PSSA tries to load this from $PSHome
30-
Add-Type -Path "$binaryModuleRoot/Newtonsoft.Json.dll"
31-
}
3226

3327
$binaryModulePath = Join-Path -Path $binaryModuleRoot -ChildPath 'Microsoft.Windows.PowerShell.ScriptAnalyzer.dll'
3428
$binaryModule = Import-Module -Name $binaryModulePath -PassThru

Tests/Documentation/RuleDocumentation.tests.ps1

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,6 @@ Describe "Validate rule documentation files" {
1515
}} |
1616
Sort-Object
1717

18-
# Remove rules from the diff list that aren't supported on old PS version
19-
if ($PSVersionTable.PSVersion.Major -eq 4) {
20-
$docs = $docs | Where-Object {$_ -notmatch '^PSAvoidGlobalAliases$'}
21-
$readmeRules = $readmeRules | Where-Object { $_ -notmatch '^PSAvoidGlobalAliases$' }
22-
}
23-
2418
$rulesDocsDiff = Compare-Object -ReferenceObject $rules -DifferenceObject $docs -SyncWindow 25
2519
$rulesReadmeDiff = Compare-Object -ReferenceObject $rules -DifferenceObject $readmeRules -SyncWindow 25
2620
}

Tests/Engine/CommunityAnalyzerRules/CommunityAnalyzerRules.psm1

Lines changed: 150 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -232,165 +232,158 @@ function Measure-RequiresModules
232232
}
233233
}
234234

235+
<#
236+
.SYNOPSIS
237+
You can store the type name in a variable or using -f operator to reduce the amount of redundant information in your script.
238+
.DESCRIPTION
239+
When interacting with classes that have long type names, you want to reduce the amount of redundant information in your script.
240+
To fix a violation of this rule, please store the type name in a variable or using -f operator. For example:
241+
$namespace = "System.Collections.{0}"; $arrayList = New-Object ($namespace -f "ArrayList"); $queue = New-Object ($namespace -f "Queue")
242+
.EXAMPLE
243+
Measure-LongClassName -CommandAst $CommandAst
244+
.INPUTS
245+
[System.Management.Automation.Language.CommandAst]
246+
.OUTPUTS
247+
[Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord[]]
248+
.NOTES
249+
Reference: 3.11. Reduce Typying for Long Class Names, Windows PowerShell Cookbook, Third Edition
250+
#>
251+
function Measure-LongClassName
252+
{
253+
[CmdletBinding()]
254+
[OutputType([Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord[]])]
255+
Param
256+
(
257+
[Parameter(Mandatory = $true)]
258+
[ValidateNotNullOrEmpty()]
259+
[System.Management.Automation.Language.CommandAst]
260+
$CommandAst
261+
)
262+
263+
Process
264+
{
265+
$results = @()
266+
267+
# The StaticParameterBinder help us to find the argument of TypeName.
268+
$spBinder = [System.Management.Automation.Language.StaticParameterBinder]
269+
270+
# Checks New-Object without ComObject parameter command only.
271+
if ($null -ne $CommandAst.GetCommandName())
272+
{
273+
if ($CommandAst.GetCommandName() -ne "new-object")
274+
{
275+
return $results
276+
}
277+
}
278+
else
279+
{
280+
return $results
281+
}
282+
283+
try
284+
{
285+
[System.Management.Automation.Language.StaticBindingResult]$sbResults = $spBinder::BindCommand($CommandAst, $true)
286+
foreach ($sbResult in $sbResults)
287+
{
288+
# TypeName cannot be found if user run command like, New-Object -ComObject Scripting.FileSystemObject.
289+
if ($null -eq $sbResult.BoundParameters["TypeName"].ConstantValue) { continue }
290+
291+
if ($sbResult.BoundParameters["TypeName"].ConstantValue.ToString().Split('.').Length -ge 3)
292+
{
293+
# $sbResult.BoundParameters["TypeName"].Value is a CommandElementAst, so we can return an extent.
294+
$result = New-Object `
295+
-Typename "Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord" `
296+
-ArgumentList $Messages.MeasureLongClassName,$sbResult.BoundParameters["TypeName"].Value.Extent,$PSCmdlet.MyInvocation.InvocationName,Information,$null
297+
298+
$results += $result
299+
}
300+
}
301+
302+
return $results
303+
}
304+
catch
305+
{
306+
$PSCmdlet.ThrowTerminatingError($PSItem)
307+
}
308+
309+
310+
}
311+
}
235312

236-
# The two rules in the following if block use StaticParameterBinder class.
237-
# StaticParameterBinder class was introduced in PSv4.
238-
if ($PSVersionTable.PSVersion -ge [Version]'4.0.0')
313+
<#
314+
.SYNOPSIS
315+
Please do not use COM objects when calling New-Object.
316+
.DESCRIPTION
317+
If you can't use just PowerShell, use .NET, external commands or COM objects, in that order of preference. COM objects are rarely well-documented, making them harder for someone else to research and understand.
318+
They do not always work flawlessly in PowerShell, as they must be used through .NET's Interop layer, which isn't 100% perfect.
319+
To fix a violation of this rule, please do not use COM objects when calling New-Object.
320+
.EXAMPLE
321+
Measure-ComObject -CommandAst $CommandAst
322+
.INPUTS
323+
[System.Management.Automation.Language.CommandAst]
324+
.OUTPUTS
325+
[Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord[]]
326+
.NOTES
327+
Reference: The Purity Laws, The Community Book of PowerShell Practices.
328+
#>
329+
function Measure-ComObject
239330
{
240-
<#
241-
.SYNOPSIS
242-
You can store the type name in a variable or using -f operator to reduce the amount of redundant information in your script.
243-
.DESCRIPTION
244-
When interacting with classes that have long type names, you want to reduce the amount of redundant information in your script.
245-
To fix a violation of this rule, please store the type name in a variable or using -f operator. For example:
246-
$namespace = "System.Collections.{0}"; $arrayList = New-Object ($namespace -f "ArrayList"); $queue = New-Object ($namespace -f "Queue")
247-
.EXAMPLE
248-
Measure-LongClassName -CommandAst $CommandAst
249-
.INPUTS
250-
[System.Management.Automation.Language.CommandAst]
251-
.OUTPUTS
252-
[Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord[]]
253-
.NOTES
254-
Reference: 3.11. Reduce Typying for Long Class Names, Windows PowerShell Cookbook, Third Edition
255-
#>
256-
function Measure-LongClassName
257-
{
258-
[CmdletBinding()]
259-
[OutputType([Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord[]])]
260-
Param
261-
(
262-
[Parameter(Mandatory = $true)]
263-
[ValidateNotNullOrEmpty()]
264-
[System.Management.Automation.Language.CommandAst]
265-
$CommandAst
266-
)
267-
268-
Process
269-
{
270-
$results = @()
271-
272-
# The StaticParameterBinder help us to find the argument of TypeName.
273-
$spBinder = [System.Management.Automation.Language.StaticParameterBinder]
274-
275-
# Checks New-Object without ComObject parameter command only.
276-
if ($null -ne $CommandAst.GetCommandName())
277-
{
278-
if ($CommandAst.GetCommandName() -ne "new-object")
279-
{
280-
return $results
281-
}
282-
}
283-
else
284-
{
285-
return $results
286-
}
287-
288-
try
289-
{
290-
[System.Management.Automation.Language.StaticBindingResult]$sbResults = $spBinder::BindCommand($CommandAst, $true)
291-
foreach ($sbResult in $sbResults)
292-
{
293-
# TypeName cannot be found if user run command like, New-Object -ComObject Scripting.FileSystemObject.
294-
if ($null -eq $sbResult.BoundParameters["TypeName"].ConstantValue) { continue }
295-
296-
if ($sbResult.BoundParameters["TypeName"].ConstantValue.ToString().Split('.').Length -ge 3)
297-
{
298-
# $sbResult.BoundParameters["TypeName"].Value is a CommandElementAst, so we can return an extent.
299-
$result = New-Object `
300-
-Typename "Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord" `
301-
-ArgumentList $Messages.MeasureLongClassName,$sbResult.BoundParameters["TypeName"].Value.Extent,$PSCmdlet.MyInvocation.InvocationName,Information,$null
302-
303-
$results += $result
304-
}
305-
}
306-
307-
return $results
308-
}
309-
catch
310-
{
311-
$PSCmdlet.ThrowTerminatingError($PSItem)
312-
}
313-
314-
315-
}
316-
}
317-
318-
<#
319-
.SYNOPSIS
320-
Please do not use COM objects when calling New-Object.
321-
.DESCRIPTION
322-
If you can't use just PowerShell, use .NET, external commands or COM objects, in that order of preference. COM objects are rarely well-documented, making them harder for someone else to research and understand.
323-
They do not always work flawlessly in PowerShell, as they must be used through .NET's Interop layer, which isn't 100% perfect.
324-
To fix a violation of this rule, please do not use COM objects when calling New-Object.
325-
.EXAMPLE
326-
Measure-ComObject -CommandAst $CommandAst
327-
.INPUTS
328-
[System.Management.Automation.Language.CommandAst]
329-
.OUTPUTS
330-
[Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord[]]
331-
.NOTES
332-
Reference: The Purity Laws, The Community Book of PowerShell Practices.
333-
#>
334-
function Measure-ComObject
335-
{
336-
[CmdletBinding()]
337-
[OutputType([Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord[]])]
338-
Param
339-
(
340-
[Parameter(Mandatory = $true)]
341-
[ValidateNotNullOrEmpty()]
342-
[System.Management.Automation.Language.CommandAst]
343-
$CommandAst
344-
)
345-
346-
Process
347-
{
348-
$results = @()
349-
350-
# The StaticParameterBinder help us to find the argument of TypeName.
351-
$spBinder = [System.Management.Automation.Language.StaticParameterBinder]
352-
353-
# Checks New-Object without ComObject parameter command only.
354-
if ($null -ne $CommandAst.GetCommandName())
355-
{
356-
if ($CommandAst.GetCommandName() -ne "new-object")
357-
{
358-
return $results
359-
}
360-
}
361-
else
362-
{
363-
return $results
364-
}
365-
366-
try
367-
{
368-
[System.Management.Automation.Language.StaticBindingResult]$sbResults = $spBinder::BindCommand($CommandAst, $true)
369-
foreach ($sbResult in $sbResults)
370-
{
371-
if ($sbResults.BoundParameters.ContainsKey("ComObject"))
372-
{
373-
# $sbResult.BoundParameters["TypeName"].Value is a CommandElementAst, so we can return an extent.
374-
$result = New-Object `
375-
-Typename "Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord" `
376-
-ArgumentList $Messages.MeasureComObject,$sbResult.BoundParameters["ComObject"].Value.Extent,$PSCmdlet.MyInvocation.InvocationName,Warning,$null
377-
378-
$results += $result
379-
}
380-
}
381-
382-
return $results
383-
}
384-
catch
385-
{
386-
$PSCmdlet.ThrowTerminatingError($PSItem)
387-
}
388-
389-
390-
}
391-
}
392-
393-
} # end if ($PSVersionTable.PSVersion -ge [Version]'4.0')
331+
[CmdletBinding()]
332+
[OutputType([Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord[]])]
333+
Param
334+
(
335+
[Parameter(Mandatory = $true)]
336+
[ValidateNotNullOrEmpty()]
337+
[System.Management.Automation.Language.CommandAst]
338+
$CommandAst
339+
)
340+
341+
Process
342+
{
343+
$results = @()
344+
345+
# The StaticParameterBinder help us to find the argument of TypeName.
346+
$spBinder = [System.Management.Automation.Language.StaticParameterBinder]
347+
348+
# Checks New-Object without ComObject parameter command only.
349+
if ($null -ne $CommandAst.GetCommandName())
350+
{
351+
if ($CommandAst.GetCommandName() -ne "new-object")
352+
{
353+
return $results
354+
}
355+
}
356+
else
357+
{
358+
return $results
359+
}
360+
361+
try
362+
{
363+
[System.Management.Automation.Language.StaticBindingResult]$sbResults = $spBinder::BindCommand($CommandAst, $true)
364+
foreach ($sbResult in $sbResults)
365+
{
366+
if ($sbResults.BoundParameters.ContainsKey("ComObject"))
367+
{
368+
# $sbResult.BoundParameters["TypeName"].Value is a CommandElementAst, so we can return an extent.
369+
$result = New-Object `
370+
-Typename "Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord" `
371+
-ArgumentList $Messages.MeasureComObject,$sbResult.BoundParameters["ComObject"].Value.Extent,$PSCmdlet.MyInvocation.InvocationName,Warning,$null
372+
373+
$results += $result
374+
}
375+
}
376+
377+
return $results
378+
}
379+
catch
380+
{
381+
$PSCmdlet.ThrowTerminatingError($PSItem)
382+
}
383+
384+
385+
}
386+
}
394387

395388

396389
<#

Tests/Engine/CustomizedRule.tests.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,15 +257,15 @@ Describe "Test importing correct customized rules" {
257257
$customizedRulePath.Count | Should -Be 1
258258
}
259259

260-
It "loads custom rules that contain version in their path" -Skip:($PSVersionTable.PSVersion -lt '5.0') {
260+
It "loads custom rules that contain version in their path" {
261261
$customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomRulePath $PSScriptRoot\VersionedSampleRule\SampleRuleWithVersion
262262
$customizedRulePath.Count | Should -Be 1
263263

264264
$customizedRulePath = Get-ScriptAnalyzerRule -CustomRulePath $PSScriptRoot\VersionedSampleRule\SampleRuleWithVersion
265265
$customizedRulePath.Count | Should -Be 1
266266
}
267267

268-
It "loads custom rules that contain version in their path with the RecurseCustomRule switch" -Skip:($PSVersionTable.PSVersion -lt '5.0') {
268+
It "loads custom rules that contain version in their path with the RecurseCustomRule switch" {
269269
$customizedRulePath = Invoke-ScriptAnalyzer $PSScriptRoot\TestScript.ps1 -CustomRulePath $PSScriptRoot\VersionedSampleRule -RecurseCustomRulePath
270270
$customizedRulePath.Count | Should -Be 1
271271

Tests/Engine/GetScriptAnalyzerRule.tests.ps1

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,6 @@ Describe "Test Name parameters" {
6464
It "get Rules with no parameters supplied" {
6565
$defaultRules = Get-ScriptAnalyzerRule
6666
$expectedNumRules = 71
67-
if ($PSVersionTable.PSVersion.Major -le 4)
68-
{
69-
# for PSv3 PSAvoidGlobalAliases is not shipped because
70-
# it uses StaticParameterBinder.BindCommand which is
71-
# available only on PSv4 and above
72-
73-
$expectedNumRules--
74-
}
7567
$defaultRules.Count | Should -Be $expectedNumRules
7668
}
7769

@@ -100,11 +92,7 @@ Describe "Test RuleExtension" {
10092
BeforeAll {
10193
$community = "CommunityAnalyzerRules"
10294
$measureRequired = "Measure-RequiresModules"
103-
$expectedNumCommunityRules = 10
104-
if ($PSVersionTable.PSVersion -ge [Version]'4.0.0')
105-
{
106-
$expectedNumCommunityRules = 12
107-
}
95+
$expectedNumCommunityRules = 12
10896
}
10997
It "with the module folder path" {
11098
$ruleExtension = Get-ScriptAnalyzerRule -CustomizedRulePath $PSScriptRoot\CommunityAnalyzerRules | Where-Object {$_.SourceName -eq $community}

0 commit comments

Comments
 (0)