Edit

UseCompatibleTypes

Severity Level: Warning

Description

This rule detects types that aren't available by default on your targeted PowerShell platforms.

A name in the PowerShell platform is identified in the following format:

<os-name>_<os-arch>_<os-version>_<ps-version>_<ps-arch>_<dotnet-version>_<dotnet-edition>

Where:

  • <os-name>: The name of the operating system PowerShell is running on. On Windows, the SKU number is included. On Linux, the value is the name of the distribution.
  • <os-arch>: The machine architecture the operating system is running on (usually x64).
  • <os-version>: The self-reported version of the operating system (the distribution version on Linux).
  • <ps-version>: The PowerShell version (from $PSVersionTable.PSVersion).
  • <ps-arch>: The machine architecture of the PowerShell process.
  • <dotnet-version>: The reported version of the .NET runtime PowerShell is running on (from System.Environment.Version).
  • <dotnet-edition>: The .NET runtime flavor PowerShell is running on (currently framework or core).

For example:

  • win-4_x64_10.0.18312.0_5.1.18312.1000_x64_4.0.30319.42000_framework is PowerShell 5.1 running on Windows 10 Enterprise (build 18312) for x64.
  • win-4_x64_10.0.18312.0_6.1.2_x64_4.0.30319.42000_core is PowerShell 6.1.2 running on the same operating system.
  • ubuntu_x64_18.04_6.2.0_x64_4.0.30319.42000_core is PowerShell 6.2.0 running on Ubuntu 18.04.

PSScriptAnalyzer includes some platform profiles as JSON files. You can target these built-in profiles directly in your configuration.

Platforms bundled by default are:

PowerShell Version Operating System ID
3.0 Windows Server 2012 win-8_x64_6.2.9200.0_3.0_x64_4.0.30319.42000_framework
4.0 Windows Server 2012 R2 win-8_x64_6.3.9600.0_4.0_x64_4.0.30319.42000_framework
5.1 Windows Server 2016 win-8_x64_10.0.14393.0_5.1.14393.2791_x64_4.0.30319.42000_framework
5.1 Windows Server 2019 win-8_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework
5.1 Windows 10 Pro win-48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework
6.2 Ubuntu 18.04 LTS ubuntu_x64_18.04_6.2.4_x64_4.0.30319.42000_core
6.2 Windows 10.0.14393 win-8_x64_10.0.14393.0_6.2.4_x64_4.0.30319.42000_core
6.2 Windows 10.0.17763 win-8_x64_10.0.17763.0_6.2.4_x64_4.0.30319.42000_core
6.2 Windows 10.0.18362 win-4_x64_10.0.18362.0_6.2.4_x64_4.0.30319.42000_core
7.0 Ubuntu 18.04 LTS ubuntu_x64_18.04_7.0.0_x64_3.1.2_core
7.0 Windows 10.0.14393 win-8_x64_10.0.14393.0_7.0.0_x64_3.1.2_core
7.0 Windows 10.0.17763 win-8_x64_10.0.17763.0_7.0.0_x64_3.1.2_core
7.0 Windows 10.0.18362 win-4_x64_10.0.18362.0_7.0.0_x64_3.1.2_core

Other profiles can be found in the GitHub repo.

You can also generate your own platform profile with the PSCompatibilityCollector module.

Compatibility settings take a list of platforms under TargetProfiles. You can specify each target platform as:

  • A platform name (for example, ubuntu_x64_18.04_6.1.1_x64_4.0.30319.42000_core). PSScriptAnalyzer appends .json and searches for it in the default profile directory.
  • A filename (for example, my_custom_platform.json), which PSScriptAnalyzer searches for in the default profile directory.
  • An absolute path to a file (like D:\PowerShellProfiles\TargetMachine.json).

The default profile directory is under the PSScriptAnalyzer module at $PSScriptRoot/PSCompatibilityCollector/profiles (where $PSScriptRoot here refers to the directory containing PSScriptAnalyzer.psd1).

The compatibility analysis compares each type you use against both a target profile and a union profile. The union profile contains every type available in any profile in the profile directory.

If a type isn't in the union profile, the rule assumes it's local to your environment and ignores it. If a type is in the union profile but missing from a target profile, the rule flags it as incompatible with that target.

Example

The following examples assume TargetProfiles includes win-48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework (Windows 10 Pro, PowerShell 5.1).

Noncompliant

System.Management.Automation.SemanticVersion isn't available by default in Windows PowerShell 5.1, so the rule flags this type usage for that target profile.

$version = [System.Management.Automation.SemanticVersion]'1.2.3'

Compliant

System.Version is available in Windows PowerShell 5.1 and PowerShell 7, so it passes compatibility checks across those targets.

$version = [System.Version]'1.2.3.0'

Configure rule

An example configuration might look like:

@{
    Rules = @{
        PSUseCompatibleTypes = @{
            Enable = $true
            TargetProfiles = @(
                'ubuntu_x64_18.04_6.1.3_x64_4.0.30319.42000_core'
                'win-48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework'
                'MyProfile'
                'another_custom_profile_in_the_profiles_directory.json'
                'D:\My Profiles\profile1.json'
            )
            # You can specify types to not check like this, which will also ignore methods and members on it:
            IgnoreTypes = @(
                'System.IO.Compression.ZipFile'
            )
        }
    }
}

Alternatively, you could provide a settings object as follows:

PS> $settings = @{
      Rules = @{
        PSUseCompatibleTypes = @{
          Enable = $true
          TargetProfiles = @('win-48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework')
        }
      }
}
PS> Invoke-ScriptAnalyzer -Settings $settings -ScriptDefinition "[System.Management.Automation.SemanticVersion]'1.18.0-rc1'"

RuleName                Severity     ScriptName Line  Message
--------                --------     ---------- ----  -------
PSUseCompatibleTypes    Warning                 1     The type 'System.Management.Automation.SemanticVersion' is
                                                      not available by default in PowerShell version
                                                      '5.1.17763.316' on platform 'Microsoft Windows 10 Pro'

Suppression

As with other rules, you can suppress type compatibility diagnostics by adding a suppression attribute to the param block of a scriptblock.

[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleTypes', '')]

You can also suppress the rule for specific types:

[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleTypes',
    'System.Management.Automation.Security.SystemPolicy')]

You can also suppress it for specific type members:

[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleTypes',
    'System.Management.Automation.LanguagePrimitives/ConvertTypeNameToPSTypeName')]

Parameters

Enable

This parameter controls whether ScriptAnalyzer checks the code against this rule. It accepts a boolean value. To enable this rule, set this parameter to $true. The default value is $false.

TargetProfiles

This parameter specifies the list of platform profiles to check compatibility against. It accepts an array of strings. Each value can be a platform name, a filename, or an absolute path to a profile file. The default value is @().

ProfileDirPath

This parameter controls the directory that ScriptAnalyzer searches for profiles by name and uses to generate the union profile. It accepts a string containing an absolute path. The default location is the compatibility_profiles directory in the PSScriptAnalyzer module.

IgnoreTypes

This parameter specifies the full names of types or type accelerators to exclude from compatibility checks. It accepts an array of type-name strings. The default value is @().