Category Archives: Powershell

New Telemetry in PowerShell 7 Preview 3

This post was originally published on this site

Beginning in PowerShell 7 Preview 3, PowerShell will be sending some additional data points to Microsoft.
This data will allow us to better understand usage of PowerShell and enable us to prioritize our future investments.
These additional points of data were reviewed with the PowerShell community and approved by the PowerShell Committee through the PowerShell RFC process.

What we added

We will continue to use Application Insights to collect the following new telemetry points:

- Count of PowerShell starts by type (API vs console)
    - Count of unique PowerShell usage
    - Count of the following execution types:
        - Application (native commands)
        - ExternalScript
        - Script
        - Function
        - Cmdlet
    - Enabled Microsoft experimental features or experimental features shipped with PowerShell
    - Count of hosted sessions
    - Microsoft owned modules loaded (based on white list)
This data will include the OS name, OS version, the PowerShell version, and the distribution channel when provided.

We will continue to share portions of our aggregated data with the PowerShell community through the
Public PowerBi report.

Why we added it

We want to make PowerShell better and believe this can be achieved by better understanding how PowerShell is being used.
Through these additional data points we will get answers backed by data to the following questions:

  • Is the PowerShell Core user-base growing?
  • How is PowerShell being used? What is the usage distribution across command types and session type?
  • How can we encourage PowerShell Core usage growth?
  • What are issues that customers are hitting in PowerShell Core?
  • What versions of PowerShell tools and services should Microsoft continue to support?
  • Which experimental features are being used and tested? Which experimental features should we invest in?
  • How can we optimize the engine size and efficiency of PowerShell for cloud scenarios?

To ensure we are getting an accurate picture of how everyone uses PowerShell, not just those most
vocal/involved in the community, we made improvements in our telemetry.
PowerShell usage telemetry will allow us to better prioritize testing, support, and investments.

Performance testing

When implementing this telemetry we took special care to ensure that there would not be a discernible performance impact.
The telemetry is collected through Application Insights and is batched and sent on a separate thread in order to reduce impact.
We also conducted tests to verify that there would not be a noticeable difference in PowerShell performance.

In order to test the performance impact of the telemetry we ran our test suite 5 times with and 5 times without the telemetry changes
and compared the average time for test completion.
The tests had a 1% difference in average completion time with the telemetry-enabled test runs actually having the faster average completion. The difference in average completion time, however, was not statistically significant.

We also tested the impact of collecting telemetry on startup time for both cold starts (first start-up of PowerShell) and warm starts (all future starts). We found that on average cold starups were .028 seconds slower with the additional telemetry while warm startups were, on average, .027 slower. The average performance impact was around 4% and all start-ups during the test runs performed faster than .6023 seconds.

How to disable

The telemetry reporting can be disabled by setting the environment variable POWERSHELL_TELEMETRY_OPTOUT to true, yes, or 1.
This should not be done in your profile, as PowerShell reads this value from your system before executing your profile.

Feedback and issues

If you encounter any issues with PowerShell telemetry, the best place to get support is through our GitHub page.

The post New Telemetry in PowerShell 7 Preview 3 appeared first on PowerShell.

PowerShell 7 Preview 3

This post was originally published on this site

PowerShell 7 Preview 3

In May, I published our PowerShell 7 Roadmap. We have been making progress on our roadmap and are currently on track to have a Generally Available (GA)
release by end of this calendar year.

Long Term Servicing

PowerShell 7 GA will also be our first Long Term Servicing (LTS) release which is a change from our current Modern Lifecycle support for PowerShell Core 6.
We will support PowerShell 7 GA for as long as .NET Core 3.1 is supported before you must upgrade to a newer version to continue to be supported by Microsoft.

Windows PowerShell compatibility

One of the main goals of PowerShell 7 is to have a viable replacement for Windows PowerShell 5.1 in production and we’ve made significant progress towards that goal.

PowerShell 7 Preview 3 is built on .NET Core 3.0 Preview 8 and leverages the work from the .NET Team to close the gap between .NET Core and .NET Framework. .NET Core 3.0 reintroduces a large number of .NET Framework APIs, opening up a large number of PowerShell modules shipped with Windows to be validated and marked as compatible by our team. Because the compatibility changes to the modules come as part of Windows, the latest version of Windows 10/Windows Server is required for full module compatibility.

However, on older versions of Windows, some modules may just work if you use:

Import-Module <moduleName> -SkipEditionCheck

If you have issues with a Microsoft PowerShell module, please open an issue in the PowerShellModuleCoverage repository!

Expect more content on this specific topic from Joey Aiello in the near future with more detail on which modules are compatible and where they’re marked as such.

New Features in Preview 3

This is just a small part of the entire changelog.
New features in this preview from the community and also the PowerShell team:

Experimental Features on by default in Preview builds

We decided to enable all Experimental Features by default in order to solicit more feedback for the PowerShell Committee to determine if a feature should continue as experimental, move from experimental to stable (non-experimental), or be withdrawn. On Stable builds (as well as Release Candidates), experimental features will continue to be disabled by default.

Note that if you had previously manually enabled experimental features, your powershell.config.jsonsettings file will take precedence and only experimental features listed within that file will be enabled. You can delete that file or run Get-ExperimentalFeature | Enable-ExperimentalFeature to ensure all experimental features are enabled. However, if you use the pipeline, you’ll have to do it again with a future Preview release that has new experimental features.

gif

Single Apartment Thread as default

In general, you don’t need to worry about a concept called ApartmentState which only applies to Windows.

Prior to this release pwsh would run as a multi-threaded apartment by default. However, graphical user interface (GUI) APIs such as WinForms and WPF require a single-threaded apartment. What is important here is that pwsh is now the same as powershell.exe in regards to apartment state and as such support calling WinForms and WPF APIs from PowerShell script.

gif

Display COM Method Signature Argument Names

On Windows, if you happen to call COM APIs from PowerShell, a new capability by nbkalex will now show the argument names of COM methods instead of just the type information which can be used as simple documentation indicating what arguments should be passed.

gif

Consider DBNull and NullString as $null

If you work with database types, you may get back a [dbnull]::Value which is equivalent to $null within the database, but in PowerShell, this was not equal to $null so you can’t compare it directly. This change from Joel Sallow allows you to compare both [dbnull]::Value and [nullstring]::Value to $null and get $true.

gif

Read-Host -Prompt works for all input

Due to how Read-Host calls into the console host and how the console host prompts for input (such as mandatory parameters that are given a value), you might encounter a situation where using Read-Host to prompt for input in your script exhibits unintended behavior when certain characters are used. This has been fixed so Read-Host will accept input as expected.

gif

Support negative numbers with -Split operator

The -Split operator splits one or more strings into substrings. You can optionally specify a value to indicate the maximum number of substrings you want returned.

This new capability by Jacob Scott now allows you to specify the maximum number of substrings as a negative value signifying that the split should happen right to left instead of the usual left to right.

gif

ForEach-Object -Parallel

We’ve received consistent feedback that PowerShell users use PSWorkflow primarily to easily run scriptblocks in parallel.

We’ve added a -Parallel parameter to ForEach-Object that accepts a scriptblock to execute in parallel. There is an optional -ThrottleLimit parameter to set the maximum threads to use in parallel where it defaults to 5.

gif

Resolve AppX reparse points

On Windows 10, if you have apps installed from the Windows Store and list them in the command line, they show up as 0 byte files. These files are actually a different type of link to the actual executable. With this change, the target executable will now show up when using Get-ChildItem.

gif

pwsh as a login shell

On Linux and macOS systems, there is a concept of a login shell which sets up the environment from which other apps and shells inherit. Prior to this release if you used pwsh as your default login shell, you may have noticed that some environment variables are missing or incomplete.

With this change, pwsh will work the same as sh Bourne Shell in how it sets up the login environment so that everything works correctly.

Additional Telemetry

In this Preview release, we’ve added more telemetry. Please see Sydney Smith‘s blog post on New Telemetry in PowerShell 7 Preview 3.

Closing

Although this blog post focuses on new features, this release also contains many bug fixes as well as targeted performance improvements.

You can always get the latest version of PowerShell from https://aka.ms/get-powershell.

Expect more new features from the community and the PowerShell team in future Preview releases!

Steve Lee
PowerShell Team

The post PowerShell 7 Preview 3 appeared first on PowerShell.

Out-GridView Returns

This post was originally published on this site

Out-GridView Returns!

It’s been almost 3 years since PowerShell Core debuted for Linux and Mac, and as we’ve increased our cmdlet coverage more and more, one cmdlet has always stood out as a top, cross-platform request. Today, we are excited to announce that Out-GridView is debuting on all Core-supported platforms through the GraphicalTools Module.

Linux Windows Mac
linux-gif window-gif macos-gif

Installation

If you want to get right to it:

Install-Module Microsoft.PowerShell.GraphicalTools

Features

Out-GridView is a visualization tool to help you deep dive into objects returned from PowerShell.

Out-GridViewImage Piping Get-Process into Out-GridView

Quick Search

Easily locate data points matching a query.

Filters

Display specific data matching only selected filters. Supports common string comparison operators, such as contains, equals, starts with, etc..

DataGrid

Rearrange, sort, and select columns to display. Auto-generates object columns based on the PowerShell format type data, expands PSObject properties if no format definition is available.

PassThru

One of the most powerful features, the -PassThru parameter lets you use the GUI to select data to send further down the pipeline.

Get-Process | Out-GridView -PassThru | Stop-Process

If you were so inclined the above script uses -PassThru to create a pretty effective emulation of Windows Task Manger.

Show Code

Sometimes, you need to automate infrequent but complex tasks where filters may be error-prone. Out-GridView can be used as a filtering tool for these cases to ensure that your filters will produce the output you expect.

Occasionally, you end up needing to repeat this automation and so it would be useful to port your existing Out-GridView workflow to a script.

Pressing the “Show-Code” button will do this for you. It will generate a PowerShell filtering script that is ready for production.

Out-GridViewImage Using Show Code to find a specific instance of VSCode

Examples of Out-GridView

The Future

We are looking for a community member to help port Show-Command and Show-Object. Check out the repository and post in the issue tracking Show-Command if you’re interested.

With the majority of the brunt work integrating PowerShell & Avalonia done, we are also open to submissions for new graphical commands or packages. A huge thanks to Adam Driscoll for showing the potential of Avalonia + PowerShell with PSAvalonia.

Lastly, check out the great work AvaloniaUI is doing for cross-platform, .NET Core-based GUIs if you haven’t already.


John Zeiders
Software Engineering Intern
PowerShell Team

The post Out-GridView Returns appeared first on PowerShell.

DSC Resource Kit Release July 2019

This post was originally published on this site

We just released the DSC Resource Kit!

This release includes updates to 11 DSC resource modules. In the past 6 weeks, 96 pull requests have been merged and 45 issues have been closed, all thanks to our amazing community!

The modules updated in this release are:

  • ActiveDirectoryDsc
  • ActiveDirectoryCSDsc
  • ComputerManagementDsc
  • SecurityPolicyDsc
  • SharePointDsc
  • SqlServerDsc
  • StorageDsc
  • xDnsServer
  • xExchange
  • xPSDesiredStateConfiguration
  • xWebAdministration

For a detailed list of the resource modules and fixes in this release, see the Included in this Release section below.

Our latest community call for the DSC Resource Kit was last Wednesday, July 31. A recording of the call is posted on the PowerShell YouTube channel. You can join us for the next call at 12PM (Pacific time) on August 28th to ask questions and give feedback about your experience with the DSC Resource Kit.

The next DSC Resource Kit release will be on Wednesday, September 8.

We strongly encourage you to update to the newest version of all modules using the PowerShell Gallery, and don’t forget to give us your feedback in the comments below, on GitHub, or on Twitter (@PowerShell_Team)!

Please see our documentation here for information on the support of these resource modules.

Included in this Release

You can see a detailed summary of all changes included in this release in the table below. For past release notes, go to the README.md or CHANGELOG.md file on the GitHub repository page for a specific module (see the How to Find DSC Resource Modules on GitHub section below for details on finding the GitHub page for a specific module).

Module Name Version Release Notes
ActiveDirectoryCSDsc 4.0.0.0
  • BREAKING CHANGE: ActiveDirectoryCSDsc module minimum requirements updated to WMF 5.0 because newly added AdcsCertificateAuthoritySettings resource requires WMF 5.0.
  • Added new resource AdcsCertificateAuthoritySettings – see Issue 13.
  • Added new resource AdcsTemplate.
  • Replaced switch blocks with if blocks for evaluating “Ensure” parameter because switch was missing break – fixes Issue 87.
  • Added Comment Based Help for New-NotImplementedException common function.
  • Moved code to create the user account for use in integration test into a CommonTestHelper.psm1 function.
  • Removed user account creation code from AppVeyor.yml and into integration tests themselves to make tests execution easier.
  • Updated user account creation code to use local user/group management Powershell cmdlets available in WMF 5.1 – fixes Issue 24.
  • AdcsCertificationAuthority:
    • Integration tests updated to create test user account in administrators group to make test execution easier.
ActiveDirectoryDsc 4.0.0.0
    The change log length exceeds the allowable limit for PowerShell Gallery. For detailed information about the changes to each resource, see the changelog.md file in the GitHub repo.

  • Changes to ActiveDirectoryDsc
  • Changes to ADManagedServiceAccount
  • Changes to ADComputer
  • Changes to ADOrganizationalUnit
  • Changes to ADUser
  • Changes to ADDomain
  • Changes to ADServicePrincipalName
  • Changes to ADDomainTrust
  • Changes to WaitForADDomain
  • Changes to ADDomainController
  • Changes to ADObjectPermissionEntry
  • Changes to ADGroup
  • Changes to ADDomainDefaultPasswordPolicy
ComputerManagementDsc 6.5.0.0
  • Computer:
    • Fix for “directory service is busy” error when joining a domain and renaming a computer when JoinOU is specified – Fixes Issue 221.
  • Added new resource SmbShare
    • Moved and improved from deprecated module xSmbShare.
  • Changes to ComputerManagementDsc.Common
    • Updated Test-DscParameterState so it now can compare zero item collections (arrays).
  • Changes to WindowsEventLog
    • Minor style guideline cleanup.
  • Opt-in to common test to validate localization. Fixed localization strings in resources – Fixes Issue 217.
  • PowerShellExecutionPolicy:
    • Removed SupportsShouldProcess as it cannot be used with DSC – Fixes Issue 219.
  • Combined all ComputerManagementDsc.ResourceHelper module functions into ComputerManagementDsc.Common module – Fixes Issue 218.
    • Minor code cleanup against style guideline.
    • Remove code from New-InvalidOperationException because it was a code path that could never could be used due to the parameter validation preventing the helper function being called that way.
    • Updated all Get-LocalizationData to latest version from DSCResource.Template.
    • Fixed an issue with the helper function Test-IsNanoServer that prevented it to work. Though the helper function is not used, so this issue was not caught until now when unit tests was added.
    • Improved code coverage.
SecurityPolicyDsc 2.9.0.0
  • Bug fix – Max password age fails when setting to 0. Fixes Issue 121
  • Bug fix – Domain_controller_LDAP_server_signing_requirements – Require Signing. Fixes Issue 122
  • Bug fix – Network_security_Restrict_NTLM security options correct parameter validation. This fix could impact your systems.
SqlServerDsc 13.1.0.0
  • Changes to SqlServerDsc
    • New DSC resource SqlAgentFailsafe
    • New DSC resource SqlDatabaseUser (issue 846).
      • Adds ability to create database users with more fine-grained control, e.g. re-mapping of orphaned logins or a different login. Supports creating a user with or without login name, and database users mapped to a certificate or asymmetric key.
    • Changes to helper function Invoke-Query
      • Fixes issues in issue 1355.
      • Works together with Connect-SQL now.
      • Parameters now match that of Connect-SQL (issue 1392).
      • Can now pass in credentials.
      • Can now pass in “Microsoft.SqlServer.Management.Smo.Server” object.
      • Can also pipe in “Microsoft.SqlServer.Management.Smo.Server” object.
      • Can pipe Connect-SQL
StorageDsc 4.7.0.0
  • Removed suppression of PSUseShouldProcessForStateChangingFunctions PSSA rule because it is no longer required.
  • Combined all StorageDsc.ResourceHelper module functions into StorageDsc.Common module and removed StorageDsc.ResourceHelper.
  • Opted into Common Tests “Common Tests – Validate Localization” – fixes Issue 206.
  • Refactored tests for StorageDsc.Common to meet latest standards.
  • Minor style corrections.
  • Removed unused localization strings from resources.
  • DiskAccessPath:
    • Added function to force refresh of disk subsystem at the start of Set-TargetResource to prevent errors occuring when the disk access path is already assigned – See Issue 121
xDnsServer 1.14.0.0
  • Copied enhancements to Test-DscParameterState from NetworkingDsc
  • Put the helper module to its own folder
  • Copied enhancements to Test-DscParameterState from NetworkingDsc
  • Put the helper module to its own folder
  • Added xDnsServerRootHint resource
  • Added xDnsServerClientSubnet resource
  • Added xDnsServerZoneScope resource
xExchange 1.28.0.0
  • Added MSFT_xExchFrontendTransportService resource, based on MSFT_xExchTransportService resource. Issue 283
  • Added unit and integration tests to the MSFT_xExchFrontendTransportService resource.
  • Added comment based help to the MSFT_xExchFrontendTransportService resource.
  • Minor style fix in MSFT_xExchEcpVirtualDirectory to ensure new PowerShell Script Analyzer custom rules pass.
xPSDesiredStateConfiguration 8.9.0.0
  • MSFT_xRemoteFile:
    • Add a retry mechanism when the download fails.
  • Fixes 631, typo in SQL connection string property name
xWebAdministration 2.7.0.0
  • Changes to xWebAdministration
    • Opt-in to the following DSC Resource Common Meta Tests:
      • Common Tests – Relative Path Length
      • Common Tests – Validate Script Files
      • Common Tests – Validate Module Files
      • Common Tests – Validate Markdown Files
      • Common Tests – Validate Markdown Links
      • Common Tests – Custom Script Analyzer Rules
      • Common Tests – Flagged Script Analyzer Rules
      • Common Tests – Required Script Analyzer Rules
      • Common Tests – Validate Example Files
    • Add ConfigurationPath to xIisMimeTypeMapping examples since it is now a required field.

How to Find Released DSC Resource Modules

To see a list of all released DSC Resource Kit modules, go to the PowerShell Gallery and display all modules tagged as DSCResourceKit. You can also enter a module’s name in the search box in the upper right corner of the PowerShell Gallery to find a specific module.

Of course, you can also always use PowerShellGet (available starting in WMF 5.0) to find modules with DSC Resources:

# To list all modules that tagged as DSCResourceKit
Find-Module -Tag DSCResourceKit 
# To list all DSC resources from all sources 
Find-DscResource

Please note only those modules released by the PowerShell Team are currently considered part of the ‘DSC Resource Kit’ regardless of the presence of the ‘DSC Resource Kit’ tag in the PowerShell Gallery.

To find a specific module, go directly to its URL on the PowerShell Gallery:
http://www.powershellgallery.com/packages/< module name >
For example:
http://www.powershellgallery.com/packages/xWebAdministration

How to Install DSC Resource Modules From the PowerShell Gallery

We recommend that you use PowerShellGet to install DSC resource modules:

Install-Module -Name < module name >

For example:

Install-Module -Name xWebAdministration

To update all previously installed modules at once, open an elevated PowerShell prompt and use this command:

Update-Module

After installing modules, you can discover all DSC resources available to your local system with this command:

Get-DscResource

How to Find DSC Resource Modules on GitHub

All resource modules in the DSC Resource Kit are available open-source on GitHub.
You can see the most recent state of a resource module by visiting its GitHub page at:
https://github.com/PowerShell/< module name >
For example, for the CertificateDsc module, go to:
https://github.com/PowerShell/CertificateDsc.

All DSC modules are also listed as submodules of the DscResources repository in the DscResources folder and the xDscResources folder.

How to Contribute

You are more than welcome to contribute to the development of the DSC Resource Kit! There are several different ways you can help. You can create new DSC resources or modules, add test automation, improve documentation, fix existing issues, or open new ones.
See our contributing guide for more info on how to become a DSC Resource Kit contributor.

If you would like to help, please take a look at the list of open issues for the DscResources repository.
You can also check issues for specific resource modules by going to:
https://github.com/PowerShell/< module name >/issues
For example:
https://github.com/PowerShell/xPSDesiredStateConfiguration/issues

Your help in developing the DSC Resource Kit is invaluable to us!

Questions, comments?

If you’re looking into using PowerShell DSC, have questions or issues with a current resource, or would like a new resource, let us know in the comments below, on Twitter (@PowerShell_Team), or by creating an issue on GitHub.

Michael Greene
Principal Program Manager
PowerShell DSC Team
@migreene (Twitter)
@mgreenegit (GitHub)

The post DSC Resource Kit Release July 2019 appeared first on PowerShell.

Introducing PowerShell as .NET Global Tool

This post was originally published on this site

PowerShell is very suitable for CI/CD scenarios due to its easy and well understood scripting paradigm,
and its cross-platform support makes it great for building and testing cross-platform applications.
A .NET Global Tool is a special NuGet package that contains a console application.

A .NET Core application can be developed for various platforms like Windows, various distributions of Linux and macOS, while the same PowerShell scripts can be used for building, testing and deployment across all platforms.

Installing PowerShell Global tool

If you already have the .NET Core SDK installed, it’s easy to install PowerShell as a .NET global tool!

dotnet tool install --global PowerShell

Once installed, you can run it with pwsh.

PowerShell in .NET SDK docker containers

PowerShell has already been included as a global tool within the .NET Core 3.0 Preview Docker images since Preview.4.
These images are a great starting point for building a .NET Core CI/CD image
(you can find some awesome samples
over at the dotnet-docker repo.)

Docker files with PowerShell syntax

As PowerShell comes pre-installed, Docker files can have PowerShell syntax.
This allows you to run scripts or cmdlets as part of your Docker file.

FROM mcr.microsoft.com/dotnet/core/sdk:3.0
RUN pwsh -c Get-Date
RUN pwsh -c "Get-Module -ListAvailable | Select-Object -Property Name, Path"

Build scenarios in Docker

In addition to enabling PowerShell syntax, PowerShell scripts in the container can be easily invoked through Docker:

docker run -it -v c:myrepo:/myrepo -w /myrepo mcr.microsoft.com/dotnet/core/sdk:3.0 pwsh ./build.ps1

The NuGet package for the global tool can be found at: https://www.nuget.org/packages/PowerShell/

Please report issues or suggestions at: https://github.com/PowerShell/PowerShell/issues/new/choose

Thank you!

Aditya Patwardhan
Senior Software Engineer
PowerShell Team
@adityapatward13

The post Introducing PowerShell as .NET Global Tool appeared first on PowerShell.

DSC Resource Kit Release June 2019

This post was originally published on this site

We just released the DSC Resource Kit!

This release includes updates to 8 DSC resource modules. In the past 6 weeks, 95 pull requests have been merged and 55 issues have been closed, all thanks to our amazing community!

The modules updated in this release are:

  • CertificateDsc
  • NetworkingDsc
  • PSDscResources
  • SharePointDsc
  • SqlServerDsc
  • xActiveDirectory
  • xDnsServer
  • xPSDesiredStateConfiguration

For a detailed list of the resource modules and fixes in this release, see the Included in this Release section below.

Our latest community call for the DSC Resource Kit was last Wednesday, June 19. A recording of the call with be posted on the PowerShell YouTube channel soon. You can join us for the next call at 12PM (Pacific time) on July 31 to ask questions and give feedback about your experience with the DSC Resource Kit.

The next DSC Resource Kit release will be on Wednesday, August 7.

We strongly encourage you to update to the newest version of all modules using the PowerShell Gallery, and don’t forget to give us your feedback in the comments below, on GitHub, or on Twitter (@PowerShell_Team)!

Please see our documentation here for information on the support of these resource modules.

Included in this Release

You can see a detailed summary of all changes included in this release in the table below. For past release notes, go to the README.md or CHANGELOG.md file on the GitHub repository page for a specific module (see the How to Find DSC Resource Modules on GitHub section below for details on finding the GitHub page for a specific module).

Module Name Version Release Notes
CertificateDsc 4.7.0.0
  • Opted into Common Tests “Common Tests – Validate Localization” – fixes Issue 195.
  • Combined all CertificateDsc.ResourceHelper module functions into CertificateDsc.Common module and renamed to CertificateDsc.CommonHelper module.
  • CertReq:
    • Fix error when ProviderName parameter is not encapsulated in double quotes – fixes Issue 185.
  • Refactor integration tests to update to latest standards.
  • Refactor unit tests to update to latest standards.
  • CertificateImport:
    • Refactor to use common functions and share more code with PfxImport resource.
    • Resource will now only throw an exception if the PFX file does not exist and it needs to be imported.
    • Removed file existence check from Path parameter to enable the resource to remove a certificate from the store without the need to have the access to the certificate file.
    • Removed ShouldProcess because it is not required by DSC Resources.
  • CertificatePfx:
    • Refactor to use common functions and share more code with CertificateImport resource.
    • Resource will now only throw an exception if the certificate file does not exist and it needs to be imported.
  • CertificateImport:
    • Added FriendlyName parameter to allow setting the certificate friendly name of the imported certificate – fixes Issue 194.
  • CertificatePfx:
    • Added FriendlyName parameter to allow setting the certificate friendly name of the imported certificate – fixes Issue 194.
NetworkingDsc 7.3.0.0
  • DnsClientGlobalSettings:
    • Fixed SuffixSearchList Empty String Handling – fixes Issue 398.
  • NetAdapterAdvancedProperty:
    • Removed validation from RegistryKeyword parameter because the list of valid registry keywords is not fixed and will depend on adapter driver – fixes Issue 388.
  • MSFT_WinsServerAddress Added MSFT_WinsServerAddress to control the WINS servers for a given network adapter.
  • Test-DscParameterState:
    • This function was enhanced with an optional reversecheck, optional internal sorting for arrays.
    • The functions ConvertTo-CimInstance and ConvertTo-Hashtable were added required by Test-DscParameterState.
  • Fix missing context message content in unit tests – fixes Issue 405.
  • Correct style violations in unit tests:
    • Adding Get, Set and Test tags to appropriate describe blocks.
    • Removing uneccesary region blocks.
    • Conversion of double quotes to single quotes where possible.
    • Replace variables with string litterals in describe block description.
  • Firewall:
    • Fix bug when LocalAddress or RemoteAddress is specified using CIDR notation with number of bits specified in subnet mask (e.g. 10.0.0.1/8) rather than using CIDR subnet mask notation (e.g 10.0.0.1/255.0.0.0) – fixes Issue 404.
PSDscResources 2.12.0.0
  • Ports style fixes that were recently made in xPSDesiredStateConfiguration on test related files.
  • Ports most of the style upgrades from xPSDesiredStateConfiguration that have been made in files in the DscResources folder.
  • Ports fixes for the following issues: Issue 505 Issue 590 Changes to test helper Enter-DscResourceTestEnvironment so that it only updates DSCResource.Tests when it is longer than 120 minutes since it was last pulled. This is to improve performance of test execution and reduce the likelihood of connectivity issues caused by inability to pull DSCResource.Tests.
  • Fixes issue where MsiPackage Integration tests fail if the test HttpListener fails to start. Moves the test HttpListener objects to dynamically assigned, higher numbered ports to avoid conflicts with other services, and also checks to ensure that the ports are available before using them. Adds checks to ensure that no outstanding HTTP server jobs are running before attempting to setup a new one. Also adds additional instrumentation to make it easier to troubleshoot issues with the test HttpListener objects in the future. Specifically fixes Issue 142
  • Improved speed of Test-IsNanoServer function
  • Remove the Byte Order Mark (BOM) from all affected files
  • Opt-in to “Validate Module Files” and “Validate Script Files” common meta-tests
  • Opt-in to “Common Tests – Relative Path Length” common meta-test
  • Fix README markdownlint validation failures
  • Move change log from README.md to CHANGELOG.md
SharePointDsc 3.5.0.0
  • SharePointDsc generic
    • Improved logging in all resource. They are now outputting the current and targeted values in the Test method.
    • Updated various resources to comply with coding style guidelines.
    • Updated the following resources to not return Null from the Get method anymore, but an hashtable which contains null values: SPDesignerSettings, SPDiagnosticLoggingSettings, SPFarmAdministrators, SPHealthAnalyzerRuleState, SPIrmSettings, SPOutgoingEmailSettings, SPPasswordChangeSettings, SPSearchTopology, SPServiceAppProxyGroup, SPTimerJobState, SPUserProfileSection, SPUserProfileSyncConnection, SPWebAppBlockedFileTypes, SPWebApplicationAppDomain, SPWebAppPolicy, SPWebAppSiteUseAndDeletion, SPWebAppThrottlingSettings, SPWordAutomationServiceApp.
  • SPConfigWizard
    • Added check to make sure the Config Wizard is only executed when all servers have the binaries installed.
  • SPDistributedCacheService
    • Added ability to check for incorrect service account.
  • SPExcelServiceApp
    • Fixes issue where Get method throws an error when the value of PrivateBytesMax and UnusedObjectAgeMax are negative values.
  • SPFarm
    • Throw error in Get method if CentralAdministrationUrl is HTTP.
  • SPInstallPrereqs
    • Fixed bug in version check, where lower versions would be detected as higher versions.
  • SPProductUpdate
    • Updated Readme to reflect the new patching possibilities added in v3.3.
  • SPSecureStore
    • Fixed issue where the test issue returned false is the service application didn’t exist, but the database name/server parameter was specified.
  • SPUserProfileSyncConnection
    • Fixed issue where the parameter Server was checked in SP2016 but isn’t used there and therefore always fails.
  • SPWebAppAuthentication
    • Updated the documentation to better explain the use of this resource when using Classic authentication.
SqlServerDsc 13.0.0.0
  • Changes to SqlServerDsc
    • Added SqlAgentAlert resource.
    • Opt-in to the common test “Common Test – Validation Localization”.
    • Opt-in to the common test “Common Test – Flagged Script Analyzer Rules” (issue 1101).
    • Removed the helper function New-TerminatingError, New-WarningMessage and New-VerboseMessage in favor of the the new localization helper functions.
    • Combine DscResource.LocalizationHelper and DscResource.Common into SqlServerDsc.Common (issue 1357).
    • Update Assert-TestEnvironment.ps1 to not error if strict mode is enabled and there are no missing dependencies (issue 1368).
  • Changes to SqlServerDsc.Common
    • Added StatementTimeout to function “Connect-SQL” with default 600 seconds (10mins).
    • Added StatementTimeout to function “Invoke-Query” with default 600 seconds (10mins) (issue 1358).
    • Changes to helper function Connect-SQL
      • The function now make it more clear that when using the parameter SetupCredential is impersonates that user, and by default it does not impersonates a user but uses the credential that the resource is run as (for example the built-in credential parameter PsDscRunAsCredential). @kungfu71186
      • Added parameter alias -DatabaseCredential for the parameter -SetupCredential. @kungfu71186
  • Changes to SqlAG
    • Added en-US localization.
  • Changes to SqlAGReplica
    • Added en-US localization.
    • Improved verbose message output when creating availability group replica, removing a availability group replica, and joining the availability group replica to the availability group.
  • Changes to SqlAlwaysOnService
    • Now outputs the correct verbose message when restarting the service.
  • Changes to SqlServerMemory
    • Now outputs the correct verbose messages when calculating the dynamic memory, and when limiting maximum memory.
  • Changes to SqlServerRole
    • Now outputs the correct verbose message when the members of a role is not in desired state.
  • Changes to SqlAgentOperator
    • Fix minor issue that when unable to connect to an instance. Instead of showing a message saying that connect failed another unrelated error message could have been shown, because of an error in the code.
    • Fix typo in test it block.
  • Changes to SqlDatabaseRole
  • Changes to SqlSetup
    • Add an Action type of “Upgrade”. This will ask setup to do a version upgrade where possible (issue 1368).
    • Fix an error when testing for DQS installation (issue 1368).
    • Changed the logic of how default value of FailoverClusterGroupName is set since that was preventing the resource to be able to be debugged (issue 448).
    • Added RSInstallMode parameter (issue 1163).
  • Changes to SqlWindowsFirewall
    • Where a version upgrade has changed paths for a database engine, the existing firewall rule for that instance will be updated rather than another one created (issue 1368). Other firewall rules can be fixed to work in the same way later.
  • Changes to SqlAGDatabase
    • Added new parameter “ReplaceExisting” with default false. This allows forced restores when a database already exists on secondary.
    • Added StatementTimeout to Invoke-Query to fix Issue1358
    • Fix issue where calling Get would return an error because the database name list may have been returned as a string instead of as a string array (issue 1368).
xActiveDirectory 3.0.0.0
  • Changes to xActiveDirectory
    • Added new helper functions in xADCommon, see each functions comment-based help for more information.
      • Convert-PropertyMapToObjectProperties
      • Compare-ResourcePropertyState
      • Test-DscPropertyState
    • Move the examples in the README.md to Examples folder.
    • Fix Script Analyzer rule failures.
    • Opt-in to the following DSC Resource Common Meta Tests:
      • Common Tests – Custom Script Analyzer Rules
      • Common Tests – Required Script Analyzer Rules
      • Common Tests – Flagged Script Analyzer Rules
      • Common Tests – Validate Module Files (issue 282)
      • Common Tests – Validate Script Files (issue 283)
      • Common Tests – Relative Path Length (issue 284)
      • Common Tests – Validate Markdown Links (issue 280)
      • Common Tests – Validate Localization (issue 281)
      • Common Tests – Validate Example Files (issue 279)
      • Common Tests – Validate Example Files To Be Published (issue 311)
    • Move resource descriptions to Wiki using auto-documentation (issue 289)
    • Move helper functions from MSFT_xADCommon to the module xActiveDirectory.Common (issue 288).
      • Removed helper function Test-ADDomain since it was not used. The helper function had design flaws too.
      • Now the helper function Test-Members outputs all the members that are not in desired state when verbose output is enabled.
    • Update all unit tests to latest unit test template.
    • Deleted the obsolete xActiveDirectory_TechNetDocumentation.html file.
    • Added new resource xADObjectEnabledState. This resource should be used to enforce the Enabled property of computer accounts. This resource replaces the deprecated Enabled property in the resource xADComputer.
    • Cleanup of code
      • Removed semicolon throughout where it is not needed.
      • Migrate tests to Pester syntax v4.x (issue 322).
      • Removed -MockWith {} in unit tests.
      • Use fully qualified type names for parameters and variables (issue 374).
    • Removed unused legacy test files from the root of the repository.
    • Updated Example List README with missing resources.
    • Added missing examples for xADReplicationSubnet, xADServicePrincipalName and xWaitForADDomain. (issue 395).
  • Changes to xADComputer
    • Refactored the resource and the unit tests.
    • BREAKING CHANGE: The Enabled property is DEPRECATED and is no longer set or enforces with this resource. If this parameter is used in a configuration a warning message will be outputted saying that the Enabled parameter has been deprecated. The new resource xADObjectEnabledState can be used to enforce the Enabled property.
    • BREAKING CHANGE: The default value of the enabled property of the computer account will be set to the default value of the cmdlet New-ADComputer.
    • A new parameter was added called EnabledOnCreation that will control if the computer account is created enabled or disabled.
    • Moved examples from the README.md to separate example files in the Examples folder.
    • Fix the RestoreFromRecycleBin description.
    • Fix unnecessary cast in Test-TargetResource (issue 295).
    • Fix ServicePrincipalNames property empty string exception (issue 382).
  • Changes to xADGroup
    • Change the description of the property RestoreFromRecycleBin.
    • Code cleanup.
  • Changes to xADObjectPermissionEntry
    • Change the description of the property IdentityReference.
    • Fix failure when applied in the same configuration as xADDomain.
    • Localize and Improve verbose messaging.
    • Code cleanup.
  • Changes to xADOrganizationalUnit
    • Change the description of the property RestoreFromRecycleBin.
    • Code cleanup.
    • Fix incorrect verbose message when this resource has Ensure set to Absent (issue 276).
  • Changes to xADUser
    • Change the description of the property RestoreFromRecycleBin.
    • Added ServicePrincipalNames property (issue 153).
    • Added ChangePasswordAtLogon property (issue 246).
    • Code cleanup.
    • Added LogonWorkstations property
    • Added Organization property
    • Added OtherName property
    • Added AccountNotDelegated property
    • Added AllowReversiblePasswordEncryption property
    • Added CompoundIdentitySupported property
    • Added PasswordNotRequired property
    • Added SmartcardLogonRequired property
    • Added ProxyAddresses property (Issue 254).
    • Fix Password property being updated whenever another property is changed (issue 384).
    • Replace Write-Error with the correct helper function (Issue 331).
  • Changes to xADDomainController
    • Change the Requires statement in the Examples to require the correct module.
    • Suppressing the Script Analyzer rule PSAvoidGlobalVars since the resource is using the $global:DSCMachineStatus variable to trigger a reboot.
    • Code cleanup.
  • Changes to xADDomain
    • Suppressing the Script Analyzer rule PSAvoidGlobalVars since the resource is using the $global:DSCMachineStatus variable to trigger a reboot.
    • Code cleanup.
  • Changes to xADDomainTrust
    • Replaced New-TerminatingError with Standard Function.
    • Code cleanup.
  • Changes to xWaitForADDomain
    • Suppressing the Script Analyzer rule PSAvoidGlobalVars since the resource is using the $global:DSCMachineStatus variable to trigger a reboot.
    • Added missing property schema descriptions (issue 369).
    • Code cleanup.
  • Changes to xADRecycleBin
    • Remove unneeded example and resource designer files.
    • Added missing property schema descriptions (issue 368).
    • Code cleanup.
    • It now sets back the $ErrorActionPreference that was set prior to setting it to "Stop".
    • Replace Write-Error with the correct helper function (issue 327).
  • Changes to xADReplicationSiteLink
    • Fix ADIdentityNotFoundException when creating a new site link.
    • Code cleanup.
  • Changes to xADReplicationSubnet
    • Remove `{ Present
xDnsServer 1.13.0.0
  • Added resource xDnsServerConditionalForwarder
  • Added xDnsServerDiagnostics resource to this module.
xPSDesiredStateConfiguration 8.8.0.0
  • Ports fix for the following issue: Issue 142 Fixes issue where MsiPackage Integration tests fail if the test HttpListener fails to start. Moves the test HttpListener objects to dynamically assigned, higher numbered ports to avoid conflicts with other services, and also checks to ensure that the ports are available before using them. Adds checks to ensure that no outstanding HTTP server jobs are running before attempting to setup a new one. Also adds additional instrumentation to make it easier to troubleshoot issues with the test HttpListener objects in the future.

How to Find Released DSC Resource Modules

To see a list of all released DSC Resource Kit modules, go to the PowerShell Gallery and display all modules tagged as DSCResourceKit. You can also enter a module’s name in the search box in the upper right corner of the PowerShell Gallery to find a specific module.

Of course, you can also always use PowerShellGet (available starting in WMF 5.0) to find modules with DSC Resources:

# To list all modules that tagged as DSCResourceKit
Find-Module -Tag DSCResourceKit
# To list all DSC resources from all sources
Find-DscResource

Please note only those modules released by the PowerShell Team are currently considered part of the ‘DSC Resource Kit’ regardless of the presence of the ‘DSC Resource Kit’ tag in the PowerShell Gallery.

To find a specific module, go directly to its URL on the PowerShell Gallery:
http://www.powershellgallery.com/packages/< module name >
For example:
http://www.powershellgallery.com/packages/xWebAdministration

How to Install DSC Resource Modules From the PowerShell Gallery

We recommend that you use PowerShellGet to install DSC resource modules:

Install-Module -Name

For example:

Install-Module -Name xWebAdministration

To update all previously installed modules at once, open an elevated PowerShell prompt and use this command:

Update-Module

After installing modules, you can discover all DSC resources available to your local system with this command:

Get-DscResource

How to Find DSC Resource Modules on GitHub

All resource modules in the DSC Resource Kit are available open-source on GitHub.
You can see the most recent state of a resource module by visiting its GitHub page at:
https://github.com/PowerShell/< module name >
For example, for the CertificateDsc module, go to:
https://github.com/PowerShell/CertificateDsc.

All DSC modules are also listed as submodules of the DscResources repository in the DscResources folder and the xDscResources folder.

How to Contribute

You are more than welcome to contribute to the development of the DSC Resource Kit! There are several different ways you can help. You can create new DSC resources or modules, add test automation, improve documentation, fix existing issues, or open new ones.
See our contributing guide for more info on how to become a DSC Resource Kit contributor.

If you would like to help, please take a look at the list of open issues for the DscResources repository.
You can also check issues for specific resource modules by going to:
https://github.com/PowerShell/< module name >/issues
For example:
https://github.com/PowerShell/xPSDesiredStateConfiguration/issues

Your help in developing the DSC Resource Kit is invaluable to us!

Questions, comments?

If you’re looking into using PowerShell DSC, have questions or issues with a current resource, or would like a new resource, let us know in the comments below, on Twitter (@PowerShell_Team), or by creating an issue on GitHub.

Katie Kragenbrink
Software Engineer
PowerShell DSC Team
@katiedsc (Twitter)
@kwirkykat (GitHub)

The post DSC Resource Kit Release June 2019 appeared first on PowerShell.

Release of PowerShell Script Analyzer 1.18.1

This post was originally published on this site

Overview

PSScriptAnalyzer (PSSA1.18.1 is now available on the PSGallery and fixes not only a lot of the issues reported for 1.18.0 but has also been made twice as faster compared to 1.18.0. Additionally, the -SaveDscDependency switch on Invoke-ScriptAnalyzerhas been improved to be platform agnostic and should now also work on Linux systems if DSC has been set up. A long standing concurrency bug related to analysing module manifest has also been fixed. Analysis showed that Test-ModuleManifest is not thread-safe due to a bug either in the cmdlet or in the PowerShell engine itself, we resolved it by having a lock around calls to this cmdlet.

Formatter Fixes

This applies especially to its usage within the VS Code PowerShell extension:

  • The new PSUseCorrectCasing formatting rule had to be adjusted to not expand/change paths and to treat wildcard characters correctly. Under the hood the rule calls Get-Command and because Get-Command ? returns all commands that have a name of length 1, it returned ForEach-Object first, which made PSSA incorrectly change the ? alias for Where-Object to ForEach-Object. The PowerShell VS Code extension has the powershell.codeFormatting.useCorrectCasing setting that wraps around this configuration and the setting is currently defaulting to false due to those issues that were found. With PSSA 1.18.1, we’d encourage you to enable the setting again as we think that we have fixed all issues and pending feedback we plan to enable the setting by default. Although the VS Code extension ships a backup version of PSSA (currently 1.18.0), one can always install PSScriptAnalyzer locally and the extension will pick it up. You can install the newer PSScriptAnalyzer version and start using it without having to wait for the extension to release an update.
  • The new PipelineIndentation configuration setting of the PSUseConsistentIndentation formatting rule had a bug when it was set to IncreaseIndentationForFirstPipeline or IncreaseIndentationAfterEveryPipeline and in certain cases, indentation of code following the pipeline could be incorrectly indented. Currently the VS Code setting powershell.codeFormatting.pipelineIndentationStyle for it is set to NoIndentation to avoid this bug. We encourage you here as well to try out the options again so that we can get feedback before we set the default of the VS Code setting to IncreaseIndentationForFirstPipeline (which is the default when calling Invoke-Formatter without parameters). This desired default was voted for by the community here.

Conclusion and Future Outlook

Please try out this new patch, if you install it using Install-Module then the VS Code extension will automatically use it after a restart of the integrated terminal session or just by re-opening VS Code. Getting feedback in this period is very important so that the PowerShell team can make a decision on when to include 1.18.1 by default in one of the next updates of the PowerShell extension. After feedback of this phased rollout, we will consider changing the default settings in the extension as mentioned above. It is hard to anticipate all the use cases, so we chose to make features configurable behind new flags and rollout the changes to a smaller user group first.

The Changelog has more details if you want to dig further.

On behalf of the Script Analyzer team,

Christoph Bergmeister, Project Maintainer from the community
Jim Truher, Senior Software Engineer, Microsoft

The post Release of PowerShell Script Analyzer 1.18.1 appeared first on PowerShell.

Get-ScriptDirectory to the Rescue

This post was originally published on this site

The other day I was writing a script and decided that I wanted to break it into a couple of files and have the main script dot-source a library script in the same directory. Here is the problem that I ran into:
PS> Get-ChildItem

Directory: Microsoft.PowerShell.CoreFileSystem::C:Temptest

Mode LastWriteTime Length Name
—- ————- —— —-
d—- 6/19/2007 6:12 AM subdir
-a— 6/19/2007 6:12 AM 47 Invoke-Test.ps1
-a— 6/19/2007 6:12 AM 47 LibraryTest.ps1

PS> Get-Content Invoke-Test.ps1
. .LibraryTest.ps1
echo “I Love PowerShell”
PS>
PS> Get-Content LibraryTest.ps1
function echo ($msg)
{ write-host $msg
}
PS>
PS> C:temptestInvoke-Test.ps1
I Love PowerShell
PS>
PS> Set-Location subdir
PS> C:temptestInvoke-Test.ps1
The term ‘.LibraryTest.ps1’ is not recognized as a cmdlet, function, opera
ble program, or script file. Verify the term and try again.
At C:temptestInvoke-Test.ps1:1 char:2
+ .
The problem is that when the script dot sources the library (“. .LibraryTest.ps1”) from the current directory, it is the current directory of the process not the directory of the script. That is why it worked when I was in the directory that had the library but it broke when I changed my location to a different directory.
What the script needs to do is to dot-source the library from its own directory (the ScriptDirectory) not the current working directory.
This brings up the question – how do I do that? (Good question!)
I didn’t know the answer off the top of my head. Well, as always with PowerShell, there is a way if you think about it for a while. Note that while it is a best practice to go explore and figure this stuff out, you can always just post a question to our newsgroup Microsoft.Public.Windows.PowerShell and the community will help.
So you do you figure this out? Let’s first start by seeing what variables are provided to a function. This is a little trickier than it sounds because in PowerShell, if you ask for a variable and it isn’t in your function’s scope, we look for it in your parent’s scope and so on until we reach to top of the stack. So the trick is to only see those variables in your scope. Check this out:
PS> function t { (Get-Variable).Count }
PS> t
72
PS> function t { (Get-Variable -Scope 0).Count }
PS> t
17
PS> # That tells us that the function has access to 72 variables but 17 are in its scope.
PS> # PowerShell populates these for each scope automatically.
PS>
PS> function t { Get-Variable -Scope 0 |sort Name}
PS> t

Name Value
—- —–
? True
args {}
ConsoleFileName
Culture en-US
ExecutionContext System.Management.Automation.EngineIntrin…
false False
HOME E:Usersjsnover.NTDEV
Host System.Management.Automation.Internal.Hos…
input System.Array+SZArrayEnumerator
MaximumVariableCount 4096
MyInvocation System.Management.Automation.InvocationInfo
null
PID 960
PSHOME E:Windowssystem32WindowsPowerShellv1.0
ShellId Microsoft.PowerShell
true True
UICulture en-US
The variable $MyInvocation is the one I was looking for so let’s explore it and see how it can help me solve this problem. Notice that I’m going to use both test scripts and the interactive shell to explore this. I’m leveraging the fact that all scopes have $MyInvocation so I can use the interactive session to explore its structure but I need a test script to test the actual values for an external script.
PS>
Get-Content t1.ps1
$MyInvocation | Format-List *
PS>
.t1.ps1

MyCommand : t1.ps1
ScriptLineNumber : 1
OffsetInLine : 9
ScriptName :
Line : .t1.ps1
PositionMessage :
At line:1 char:9
+ .t1.ps1 # Note the LACK of a PATH. Let’s explore the structure of MyInvocation
PS> # to see if we can find one.
PS> $MyInvocation |Get-Member -type Property

TypeName: System.Management.Automation.InvocationInfo

Name MemberType Definition
—- ———- ———-
InvocationName Property System.String InvocationName {get;}
Line Property System.String Line {get;}
MyCommand Property
System.Management.Automation.CommandInfo
MyC…
OffsetInLine Property System.Int32 OffsetInLine {get;}
PipelineLength Property System.Int32 PipelineLength {get;}
PipelinePosition Property System.Int32 PipelinePosition {get;}
PositionMessage Property System.String PositionMessage {get;}
ScriptLineNumber Property System.Int32 ScriptLineNumber {get;}
ScriptName Property System.String ScriptName {get;}

PS>
# Notice that MyCommand is a structure (not a simple type) so let’s explore it.
PS> $MyInvocation.MyCommand |Get-Member -Type Property

TypeName: System.Management.Automation.ScriptInfo

Name MemberType Definition
—- ———- ———-
CommandType Property System.Management.Automation.CommandTypes Command…
Definition Property System.String Definition {get;}
Name Property System.String Name {get;}
ScriptBlock Property System.Management.Automation.ScriptBlock ScriptBl…

PS>
# Looks promising.
PS>
Get-Content t2.ps1
$MyInvocation.MyCommand | Format-List *
PS> .t2.ps1

Path : C:Temptestsubdirt2.ps1
Definition : C:Temptestsubdirt2.ps1
Name : t2.ps1
CommandType : ExternalScript

PS>
# BINGO!
So with that knowledge I can now write my Get-ScriptDirectory function and use it dot-source a local library properly. Now think about this a second, if you write a function Get-ScriptDirectory and call it, $MyInvocation is going to be changed and reflect the call to that function. So what this function has to do is to work on the $MyInvocation of its parent! Luckly, the PowerShell team thought of that and the Get-Variable cmdlet allows you to specify a SCOPE. If you specify 0, it means the current scope (you saw this earlier). If you specify 1, it means the parent scope (2 means the grandparent and so on). So here it is:
PS> Get-Content Invoke-Test.ps1
function Get-ScriptDirectory
{
$Invocation = (Get-Variable MyInvocation -Scope 1).Value
Split-Path $Invocation.MyCommand.Path
}

$path = Join-Path (Get-ScriptDirectory) LibraryTest.ps1
. $path
echo “I Love PowerShell”
PS>
PS> C:TemptestInvoke-Test.ps1
I Love PowerShell
PS>
PS> Set-Location subdir
PS>
PS> C:TemptestInvoke-Test.ps1
I Love PowerShell
PS>
PS>
# If it can work there, it can work anywhere!
I just love this stuff!!!!
Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

The post Get-ScriptDirectory to the Rescue appeared first on PowerShell.

DSC Resource Kit Release May 2019

This post was originally published on this site

We just released the DSC Resource Kit! This release includes updates to 14 DSC resource modules. In the past 6 weeks, 87 pull requests have been merged and 36 issues have been closed, all thanks to our amazing community!

The modules updated in this release are:

  • ActiveDirectoryCSDsc
  • CertificateDsc
  • ComputerManagementDsc
  • NetworkingDsc
  • OfficeOnlineServerDsc
  • PSDscResources
  • SharePointDsc
  • SqlServerDsc
  • StorageDsc
  • xActiveDirectory
  • xDnsServer
  • xFirefox
  • xPSDesiredStateConfiguration
  • xWebAdministration

For a detailed list of the resource modules and fixes in this release, see the Included in this Release section below.

Our latest community call for the DSC Resource Kit was last Wednesday, May 8. A recording of the call is available here. You can join us for the next call at 12PM (Pacific time) on June 19 to ask questions and give feedback about your experience with the DSC Resource Kit.

The next DSC Resource Kit release will be on Wednesday, June 26.

We strongly encourage you to update to the newest version of all modules using the PowerShell Gallery, and don’t forget to give us your feedback in the comments below, on GitHub, or on Twitter (@PowerShell_Team)!

Please see our documentation here for information on the support of these resource modules.

Included in this Release

You can see a detailed summary of all changes included in this release in the table below. For past release notes, go to the README.md or CHANGELOG.md file on the GitHub repository page for a specific module (see the How to Find DSC Resource Modules on GitHub section below for details on finding the GitHub page for a specific module).

Module Name Version Release Notes
ActiveDirectoryCSDsc 3.3.0.0
  • Remove reference to StorageDsc in README.md – fixes Issue 76.
  • Combined all ActiveDirectoryCSDsc.ResourceHelper module functions into ActiveDirectoryCSDsc.Common module and renamed to ActiveDirectoryCSDsc.CommonHelper module.
  • Opted into Common Tests “Common Tests – Validate Localization” – fixes Issue 82.
CertificateDsc 4.6.0.0
  • CertReq:
    • Added Compare-CertificateIssuer function to checks if the Certificate Issuer matches the CA Root Name.
    • Changed Compare-CertificateSubject function to return false if ReferenceSubject is null.
    • Fixed exception when Certificate with empty Subject exists in Certificate Store – fixes Issue 190.
    • Fixed bug matching existing certificate when Subject Alternate Name is specified and machine language is not en-US – fixes Issue 193.
    • Fixed bug matching existing certificate when Template Name is specified and machine language is not en-US – fixes Issue 193.
    • Changed Import-CertificateEx function to use X509Certificate2Collection instead of X509Certificate2 to support importing certificate chains
ComputerManagementDsc 6.4.0.0
  • ScheduledTask:
    • IdleWaitTimeout returned from Get-TargetResource always null – Fixes Issue 186.
    • Added BuiltInAccount Property to allow running task as one of the build in service accounts – Fixes Issue 130.
  • Refactored module folder structure to move resource to root folder of repository and remove test harness – fixes Issue 188.
  • Added a CODE_OF_CONDUCT.md with the same content as in the README.md and linked to it from README.MD instead.
  • Updated test header for all unit tests to version 1.2.4.
  • Updated test header for all imtegration to version 1.3.3.
  • Enabled example publish to PowerShell Gallery by adding gallery_api environment variable to AppVeyor.yml.
NetworkingDsc 7.2.0.0
  • NetAdapterAdvancedProperty:
    • Added support for RegistryKeyword MaxRxRing1Length and NumRxBuffersSmall – fixes Issue 387.
  • Firewall:
    • Prevent “Parameter set cannot be resolved using the specified named parameters” error when updating rule when group name is specified – fixes Issue 130 and Issue 191.
  • Opted into Common Tests “Common Tests – Validate Localization” – fixes Issue 393.
  • Combined all NetworkingDsc.ResourceHelper module functions into NetworkingDsc.Common module – fixes Issue 394.
  • Renamed all localization strings so that they are detected by “Common Tests – Validate Localization”.
  • Fixed issues with mismatched localization strings.
  • Updated all common functions with the latest versions from DSCResource.Template.
  • Fixed an issue with the helper function Test-IsNanoServer that prevented it to work. Though the helper function is not used, so this issue was not caught until now when unit tests was added.
  • Corrected style violations in NetworkingDsc.Common.
OfficeOnlineServerDsc 1.4.0.0
  • OfficeOnlineServerInstall
    • Updated resource to make sure the Windows Environment variables are loaded into the PowerShell session;
  • OfficeOnlineServerMachine
    • Updated resource to make sure the Windows Environment variables are loaded into the PowerShell session;
  • Created LICENSE file to match the Microsoft Open Source Team standard.
PSDscResources 2.11.0.0
  • Fix Custom DSC Resource Kit PSSA Rule Failures
SharePointDsc 3.4.0.0
  • SPDistributedCacheClientSettings
    • Added 15 new SharePoint 2016 parameters.
  • SPFarm
    • Implemented Null check in Get method to prevent errors
    • Add support to provision Central Administration on HTTPS
  • SPInfoPathFormsServiceConfig
    • Added the AllowEventPropagation parameter.
  • SPInstall
    • Improved logging ouput
    • Updated blocked setup file check to prevent errors when BinaryDir is a CD-ROM drive or mounted ISO
  • SPInstallLanguagePack
    • Improved logging ouput
    • Updated blocked setup file check to prevent errors when BinaryDir is a CD-ROM drive or mounted ISO
  • SPInstallPrereqs
    • Improved logging ouput
    • Added the updated check to unblock setup file if it is blocked because it is coming from a network location. This to prevent endless wait.
    • Added ability to install from a UNC path, by adding server to IE Local Intranet Zone. This will prevent an endless wait caused by security warning.
    • Fixed an issue that would prevent the resource failing a test when the prerequisites have been installed successfully on Windows Server 2019
  • SPManagedMetadataServiceApp
    • Fixed issue where Get-TargetResource method throws an error when the service app proxy does not exist and no proxy name is specified.
  • SPProductUpdate
    • Improved logging ouput
    • Updated blocked setup file check to prevent errors when SetupFile is a CD-ROM drive or mounted ISO
  • SPSearchContent Source
    • Removed check that prevents configuring an incremental schedule when using continuous crawl.
  • SPSitePropertyBag
    • Fixed issue where properties were set on the wrong level.
  • SPSubscriptionSettingsServiceApp
    • Fixed issue where the service app proxy isn’t created when it wasn’t created during initial deployment.
  • SPTrustedRootAuthority
    • Added possibility to get certificate from file.
SqlServerDsc 12.5.0.0
  • Changes to SqlServerSecureConnection
    • Updated README and added example for SqlServerSecureConnection, instructing users to use the “SYSTEM” service account instead of “LocalSystem”.
  • Changes to SqlScript
    • Correctly passes the $VerbosePreference to the helper function Invoke-SqlScript so that PRINT statements is outputted correctly when verbose output is requested, e.g Start-DscConfiguration -Verbose.
    • Added en-US localization (issue 624).
    • Added additional unit tests for code coverage.
  • Changes to SqlScriptQuery
    • Correctly passes the $VerbosePreference to the helper function Invoke-SqlScript so that PRINT statements is outputted correctly when verbose output is requested, e.g Start-DscConfiguration -Verbose.
    • Added en-US localization.
    • Added additional unit tests for code coverage.
  • Changes to SqlSetup
    • Concatenated Robocopy localization strings (issue 694).
    • Made the error message more descriptive when the Set-TargetResource function calls the Test-TargetResource function to verify the desired state.
  • Changes to SqlWaitForAG
  • Changes to SqlServerPermission
  • Changes to SqlServerMemory
    • Added en-US localization (issue 617).
    • No longer will the resource set the MinMemory value if it was provided in a configuration that also set the Ensure parameter to “Absent” (issue 1329).
    • Refactored unit tests to simplify them add add slightly more code coverage.
  • Changes to SqlServerMaxDop
  • Changes to SqlRS
    • Reporting Services are restarted after changing settings, unless $SuppressRestart parameter is set (issue 1331). $SuppressRestart will also prevent Reporting Services restart after initialization.
    • Fixed one of the error handling to use localization, and made the error message more descriptive when the Set-TargetResource function calls the Test-TargetResource function to verify the desired state. This was done prior to adding full en-US localization.
    • Fixed (issue 1258). When initializing Reporting Services, there is no need to execute InitializeReportServer CIM method, since executing SetDatabaseConnection CIM method initializes Reporting Services.
    • issue 864 SqlRs can now initialise SSRS 2017 instances
  • Changes to SqlServerLogin
    • Added en-US localization (issue 615).
    • Added unit tests to improved code coverage.
  • Changes to SqlWindowsFirewall
  • Changes to SqlServerEndpoint
  • Changes to SqlServerEndpointPermission
  • Changes to SqlServerEndpointState
  • Changes to SqlDatabaseRole
  • Changes to SqlDatabaseRecoveryModel
  • Changes to SqlDatabasePermission
  • Changes to SqlDatabaseOwner
  • Changes to SqlDatabase
  • Changes to SqlAGListener
  • Changes to SqlAlwaysOnService
  • Changes to SqlAlias
    • Added en-US localization (issue 602).
    • Removed ShouldProcess for the code, since it has no purpose in a DSC resource (issue 242).
  • Changes to SqlServerReplication
    • Added en-US localization (issue 620).
    • Refactored Get-TargetResource slightly so it provide better verbose messages.
StorageDsc 4.7.0.0
  • DiskAccessPath:
    • Added a Get-Partition to properly handle setting the NoDefaultDriveLetter parameter – fixes Issue 198.
xActiveDirectory 2.26.0.0
  • Changes to xActiveDirectory
    • Added localization module -DscResource.LocalizationHelper* containing the helper functions Get-LocalizedData, New-InvalidArgumentException, New-InvalidOperationException, New-ObjectNotFoundException, and New-InvalidResultException (issue 257). For more information around these helper functions and localization in resources, see Localization section in the Style Guideline.
    • Added common module DscResource.Common containing the helper function Test-DscParameterState. The goal is that all resource common functions are moved to this module (functions that are or can be used by more than one resource) (issue 257).
    • Added xADManagedServiceAccount resource to manage Managed Service Accounts (MSAs). Andrew Wickham (@awickham10) and @kungfu71186
    • Removing the Misc Folder, as it is no longer required.
    • Added xADKDSKey resource to create KDS Root Keys for gMSAs. @kungfu71186
    • Combined DscResource.LocalizationHelper and DscResource.Common Modules into xActiveDirectory.Common
  • Changes to xADReplicationSiteLink
    • Make use of the new localization helper functions.
  • Changes to xAdDomainController
    • Added new parameter to disable or enable the Global Catalog (GC) (issue 75). Eric Foskett @Merto410
    • Fixed a bug with the parameter InstallationMediaPath that it would not be added if it was specified in a configuration. Now the parameter InstallationMediaPath is correctly passed to Install-ADDSDomainController.
    • Refactored the resource with major code cleanup and localization.
    • Updated unit tests to latest unit test template and refactored the tests for the function “Set-TargetResource”.
    • Improved test code coverage.
  • Changes to xADComputer
    • Restoring a computer account from the recycle bin no longer fails if there is more than one object with the same name in the recycle bin. Now it uses the object that was changed last using the property whenChanged (issue 271).
  • Changes to xADGroup
    • Restoring a group from the recycle bin no longer fails if there is more than one object with the same name in the recycle bin. Now it uses the object that was changed last using the property whenChanged (issue 271).
  • Changes to xADOrganizationalUnit
    • Restoring an organizational unit from the recycle bin no longer fails if there is more than one object with the same name in the recycle bin. Now it uses the object that was changed last using the property whenChanged (issue 271).
  • Changes to xADUser
    • Restoring a user from the recycle bin no longer fails if there is more than one object with the same name in the recycle bin. Now it uses the object that was changed last using the property whenChanged (issue 271).
xDnsServer 1.12.0.0
  • Update appveyor.yml to use the default template.
  • Added default template files .codecov.yml, .gitattributes, and .gitignore, and .vscode folder.
  • Added UseRootHint property to xDnsServerForwarder resource.
xFirefox 1.3.0.0
  • Update appveyor.yml to use the default template.
  • Added default template files .codecov.yml, .gitattributes, and .gitignore, and .vscode folder.
  • The module manifest now contains the correct PowerShell version.
  • Added xFirefoxPreference Resource to automate Firefox Preference Configuration
xPSDesiredStateConfiguration 8.7.0.0
  • MSFT_xWindowsProcess:
    • Fixes issue where a process will fail to be created if a $Path is passed that contains one or more spaces, and the resource is using $Credentials.
    • Fixes issue where a process will fail to be created if $Arguments are passed that contain one or more spaces (with or without credentials).
    • Fixes issue where Integration tests fail if empty Arguments are passed. issue 605
    • Heavily refactors MSFT_xWindowsProcess.Integration.Tests.ps1 and adds more Path and Arguments related test cases.
    • Removes reliance on test file WindowsProcessTestProcess.
  • Fixes test failures in xWindowsOptionalFeatureSet.Integration.Tests.ps1 due to accessing the windowsOptionalFeatureName variable before it is assigned. issue 612
  • MSFT_xDSCWebService
    • Fixes issue 536 and starts the deprecation process for configuring a windows firewall (exception) rule using xDSCWebService
    • Fixes issue 463 and fixes some bugs introduced with the new firewall rule handling
xWebAdministration 2.6.0.0
  • Changed order of classes in schema.mof files to workaround 423
  • Fix subject comparison multiple entries for helper function Find-Certificate that could not find the test helper function Install-NewSelfSignedCertificateExScript.
  • Updated unit test for helper function Find-Certificate to check for multiple subject names in different orders.

How to Find Released DSC Resource Modules

To see a list of all released DSC Resource Kit modules, go to the PowerShell Gallery and display all modules tagged as DSCResourceKit. You can also enter a module’s name in the search box in the upper right corner of the PowerShell Gallery to find a specific module.

Of course, you can also always use PowerShellGet (available starting in WMF 5.0) to find modules with DSC Resources:

#To list all modules that tagged as DSCResourceKit
Find-Module -Tag DSCResourceKit 
#To list all DSC resources from all sources
Find-DscResource

Please note only those modules released by the PowerShell Team are currently considered part of the ‘DSC Resource Kit’ regardless of the presence of the ‘DSC Resource Kit’ tag in the PowerShell Gallery.

To find a specific module, go directly to its URL on the PowerShell Gallery:
http://www.powershellgallery.com/packages/< module name >
For example:
http://www.powershellgallery.com/packages/xWebAdministration

How to Install DSC Resource Modules From the PowerShell Gallery

We recommend that you use PowerShellGet to install DSC resource modules:

Install-Module -Name < module name >

For example:

Install-Module -Name xWebAdministration

To update all previously installed modules at once, open an elevated PowerShell prompt and use this command:

Update-Module

After installing modules, you can discover all DSC resources available to your local system with this command:

Get-DscResource

How to Find DSC Resource Modules on GitHub

All resource modules in the DSC Resource Kit are available open-source on GitHub.
You can see the most recent state of a resource module by visiting its GitHub page at:
https://github.com/PowerShell/< module name >
For example, for the CertificateDsc module, go to:
https://github.com/PowerShell/CertificateDsc.

All DSC modules are also listed as submodules of the DscResources repository in the DscResources folder and the xDscResources folder.

How to Contribute

You are more than welcome to contribute to the development of the DSC Resource Kit! There are several different ways you can help. You can create new DSC resources or modules, add test automation, improve documentation, fix existing issues, or open new ones.
See our contributing guide for more info on how to become a DSC Resource Kit contributor.

If you would like to help, please take a look at the list of open issues for the DscResources repository.
You can also check issues for specific resource modules by going to:
https://github.com/PowerShell/< module name >/issues
For example:
https://github.com/PowerShell/xPSDesiredStateConfiguration/issues

Your help in developing the DSC Resource Kit is invaluable to us!

Questions, comments?

If you’re looking into using PowerShell DSC, have questions or issues with a current resource, or would like a new resource, let us know in the comments below, on Twitter (@PowerShell_Team), or by creating an issue on GitHub.

Katie Kragenbrink
Software Engineer
PowerShell DSC Team
@katiedsc (Twitter)
@kwirkykat (GitHub)

The post DSC Resource Kit Release May 2019 appeared first on PowerShell.

Using PSScriptAnalyzer to check PowerShell version compatibility

This post was originally published on this site

PSScriptAnalyzer version 1.18 was released recently, and ships with powerful new rules that can check PowerShell scripts for incompatibilities with other PowerShell versions and environments.

In this blog post, the first in a series, we’ll see how to use these new rules to check a script for problems running on PowerShell 3, 5.1 and 6.

Wait, what’s PSScriptAnalyzer?

PSScriptAnalzyer is a module providing static analysis (or linting) and some dynamic analysis (based on the state of your environment) for PowerShell. It’s able to find problems and fix bad habits in PowerShell scripts as you create them, similar to the way the C# compiler will give you warnings and find errors in C# code before it’s executed.

If you use the VSCode PowerShell extension, you might have seen the “green squigglies” and problem reports that PSScriptAnalyzer generates for scripts you author:

Image of PSScriptAnalyzer linting in VSCode with green squigglies

You can install PSScriptAnalyzer to use on your own scripts with:

Install-Module PSScriptAnalyzer -Scope CurrentUser

PSScriptAnalyzer works by running a series of rules on your scripts, each of which independently assesses some issue. For example AvoidUsingCmdletAliases checks that aliases aren’t used in scripts, and MisleadingBackticks checks that backticks at the ends of lines aren’t followed by whitespace.

For more information, see the PSScriptAnalyzer deep dive blog series.

Introducing the compatibility check rules

The new compatibility checking functionality is provided by three new rules:

  • PSUseCompatibleSyntax, which checks whether a syntax used in a script will work in other PowerShell versions.
  • PSUseCompatibleCommands, which checks whether commands used in a script are available in other PowerShell environments.
  • PSUseCompatibleTypes, which checks whether .NET types and static methods/properties are available in other PowerShell environments.

The syntax check rule simply requires a list of PowerShell versions you want to target, and will tell you if a syntax used in your script won’t work in any of those versions.

The command and type checking rules are more sophisticated and rely on profiles (catalogs of commands and types available) from commonly used PowerShell platforms. They require configuration to use these profiles, which we’ll go over below.

For this post, we’ll look at configuring and using PSUseCompatibleSyntax and PSUseCompatibleCommands to check that a script works with different versions of PowerShell. We’ll look at PSUseCompatibleTypes in a later post, although it’s configured very similarly to PSUseCompatibleCommands.

Working example: a small PowerShell script

Imagine we have a small (and contrived) archival script saved to .archiveScript.ps1:

# Import helper module to get folders to archive
Import-Module -FullyQualifiedName @{ ModuleName = ArchiveHelper; ModuleVersion = '1.1' }

$paths = Get-FoldersToArchive -RootPath 'C:DocumentsDocumentsToArchive'
$archiveBasePath = 'ArchiveServerDocumentArchive'

# Dictionary to collect hashes
$hashes = [System.Collections.Generic.Dictionary[string, string]]::new()
foreach ($path in $paths)
{
    # Get the hash of the file and turn it into a base64 string
    $hash = (Get-FileHash -LiteralPath $path).Hash

    # Add this file to the hash catalog
    $hashes[$hash] = $path

    # Now give the archive a unique name and zip it up
    $name = Split-Path -LeafBase $path
    Compress-Archive -LiteralPath $path -DestinationPath (Join-Path $archiveBasePath "$name-$hash.zip")
}

# Add the hash catalog to the archive directory
ConvertTo-Json $hashes | Out-File -LiteralPath (Join-Path $archiveBasePath "catalog.json") -NoNewline

This script was written in PowerShell 6.2, and we’ve tested that it works there. But we also want to run it on other machines, some of which run PowerShell 5.1 and some of which run PowerShell 3.0.

Ideally we will test it on those other platforms, but it would be nice if we could try to iron out as many bugs as possible ahead of time.

Checking syntax with PSUseCompatibleSyntax

The first and easiest rule to apply is PSUseCompatibleSyntax. We’re going to create some settings for PSScriptAnalyzer to enable the rule, and then run analysis on our script to get back any diagnostics about compatibility.

Running PSScriptAnalyzer is straightforward. It comes as a PowerShell module, so once it’s installed on your module path you just invoke it on your file with Invoke-ScriptAnalyzer, like this:

Invoke-ScriptAnalyzer -Path '.archiveScript.ps1`

A very simple invocation like this one will run PSScriptAnalyzer using its default rules and configurations on the script you point it to.

However, because they require more targeted configuration, the compatibility rules are not enabled by default. Instead, we need to supply some settings to run the syntax check rule. In particular, PSUseCompatibleSyntax requires a list of the PowerShell versions you are targeting with your script.

$settings = @{
    Rules = @{
        PSUseCompatibleSyntax = @{
            # This turns the rule on (setting it to false will turn it off)
            Enable = $true

            # List the targeted versions of PowerShell here
            TargetVersions = @(
                '3.0',
                '5.1',
                '6.2'
            )
        }
    }
}

Invoke-ScriptAnalyzer -Path .archiveScript.ps1 -Settings $settings

Running this will present us with the following output:

RuleName                            Severity     ScriptName Line  Message
--------                            --------     ---------- ----  -------
PSUseCompatibleSyntax               Warning      archiveScr 8     The constructor syntax
                                                 ipt.ps1          '[System.Collections.Generic.Dictionary[string,
                                                                  string]]::new()' is not available by default in
                                                                  PowerShell versions 3,4

This is telling us that the [dictionary[string, string]]::new() syntax we used won’t work in PowerShell 3. Better than that, in this case the rule has actually proposed a fix:

$diagnostics = Invoke-ScriptAnalyzer -Path .archiveScript.ps1 -Settings $settings
$diagnostics[0].SuggestedCorrections
File              : C:UsersroholtDocumentsDevsandboxVersionedScriptarchiveScript.ps1
Description       : Use the 'New-Object @($arg1, $arg2, ...)' syntax instead for compatibility with PowerShell versions 3,4
StartLineNumber   : 8
StartColumnNumber : 11
EndLineNumber     : 8
EndColumnNumber   : 73
Text              : New-Object 'System.Collections.Generic.Dictionary[string,string]'
Lines             : {New-Object 'System.Collections.Generic.Dictionary[string,string]'}
Start             : Microsoft.Windows.PowerShell.ScriptAnalyzer.Position
End               : Microsoft.Windows.PowerShell.ScriptAnalyzer.Position

The suggested correction is to use New-Object instead. The way this is suggested might seem slightly unhelpful here with all the position information, but we’ll see later why this is useful.

This dictionary example is a bit artificial of course (since a hashtable would come more naturally), but having a spanner thrown into the works in PowerShell 3 or 4 because of a ::new() is not uncommon. The PSUseCompatibleSyntax rule will also warn you about classes, workflows and using statements depending on the versions of PowerShell you’re authoring for.

We’re not going to make the suggested change just yet, since there’s more to show you first.

Checking command usage with PSUseCompatibleCommands

We now want to check the commands. Because command compatibility is a bit more complicated than syntax (since the availability of commands depends on more than what version of PowerShell is being run), we have to target profiles instead.

Profiles are catalogs of information taken from stock machines running common PowerShell environments. The ones shipped in PSScriptAnalyzer can’t always match your working environment perfectly, but they come pretty close (there’s also a way to generate your own profile, detailed in a later blog post). In our case, we’re trying to target PowerShell 3.0, PowerShell 5.1 and PowerShell 6.2 on Windows. We have the first two profiles, but in the last case we’ll need to target 6.1 instead. These targets are very close, so warnings will still be pertinent to using PowerShell 6.2. Later when a 6.2 profile is made available, we’ll be able to switch over to that.

We need to look under the PSUseCompatibleCommands documentation for a list of profiles available by default. For our desired targets we pick:

  • PowerShell 6.1 on Windows Server 2019 (win-8_x64_10.0.14393.0_6.1.3_x64_4.0.30319.42000_core)
  • PowerShell 5.1 on Windows Server 2019 (win-8_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework)
  • PowerShell 3.0 on Windows Server 2012 (win-8_x64_6.2.9200.0_3.0_x64_4.0.30319.42000_framework)

The long names on the right are canonical profile identifiers, which we use in the settings:

$settings = @{
    Rules = @{
        PSUseCompatibleCommands = @{
            # Turns the rule on
            Enable = $true

            # Lists the PowerShell platforms we want to check compatibility with
            TargetProfiles = @(
                'win-8_x64_10.0.14393.0_6.1.3_x64_4.0.30319.42000_core',
                'win-8_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework',
                'win-8_x64_6.2.9200.0_3.0_x64_4.0.30319.42000_framework'
            )
        }
    }
}

Invoke-ScriptAnalyzer -Path ./archiveScript.ps1 -Settings $settings

There might be a delay the first time you execute this because the rules have to load the catalogs into a cache. Each catalog of a PowerShell platform contains details of all the modules and .NET assemblies available to PowerShell on that platform, which can be as many as 1700 commands with 15,000 parameters and 100 assemblies with 10,000 types. But once it’s loaded, further compatibility analysis will be fast. We get output like this:

RuleName                            Severity     ScriptName Line  Message
--------                            --------     ---------- ----  -------
PSUseCompatibleCommands             Warning      archiveScr 2     The parameter 'FullyQualifiedName' is not available for
                                                 ipt.ps1          command 'Import-Module' by default in PowerShell version
                                                                  '3.0' on platform 'Microsoft Windows Server 2012
                                                                  Datacenter'
PSUseCompatibleCommands             Warning      archiveScr 12    The command 'Get-FileHash' is not available by default in
                                                 ipt.ps1          PowerShell version '3.0' on platform 'Microsoft Windows
                                                                  Server 2012 Datacenter'
PSUseCompatibleCommands             Warning      archiveScr 18    The parameter 'LeafBase' is not available for command
                                                 ipt.ps1          'Split-Path' by default in PowerShell version
                                                                  '5.1.17763.316' on platform 'Microsoft Windows Server
                                                                  2019 Datacenter'
PSUseCompatibleCommands             Warning      archiveScr 18    The parameter 'LeafBase' is not available for command
                                                 ipt.ps1          'Split-Path' by default in PowerShell version '3.0' on
                                                                  platform 'Microsoft Windows Server 2012 Datacenter'
PSUseCompatibleCommands             Warning      archiveScr 19    The command 'Compress-Archive' is not available by
                                                 ipt.ps1          default in PowerShell version '3.0' on platform
                                                                  'Microsoft Windows Server 2012 Datacenter'
PSUseCompatibleCommands             Warning      archiveScr 23    The parameter 'NoNewline' is not available for command
                                                 ipt.ps1          'Out-File' by default in PowerShell version '3.0' on
                                                                  platform 'Microsoft Windows Server 2012 Datacenter'

This is telling us that:

  • Import-Module doesn’t support -FullyQualifiedName in PowerShell 3.0;
  • Get-FileHash doesn’t exist in PowerShell 3.0;
  • Split-Path doesn’t have -LeafBase in PowerShell 5.1 or PowerShell 3.0;
  • Compress-Archive isn’t available in PowerShell 3.0, and;
  • Out-File doesn’t support -NoNewline in PowerShell 3.0

One thing you’ll notice is that the Get-FoldersToArchive function is not being warned about. This is because the compatibility rules are designed to ignore user-provided commands; a command will only be marked as incompatible if it’s present in some profile and not in one of your targets.

Again, we can change the script to fix these warnings, but before we do, I want to show you how to make this a more continuous experience; as you change your script, you want to know if the changes you make break compatibility, and that’s easy to do with the steps below.

Using a settings file for repeated invocation

The first thing we want is to make the PSScriptAnalyzer invocation more automated and reproducible. A nice step toward this is taking the settings hashtable we made and turning it into a declarative data file, separating out the “what” from the “how”.

PSScriptAnalyzer will accept a path to a PSD1 in the -Settings parameter, so all we need to do is turn our hashtable into a PSD1 file, which we’ll make ./PSScriptAnalyzerSettings.psd1. Notice we can merge the settings for both PSUseCompatibleSyntax and PSUseCompatibleCommands:

# PSScriptAnalyzerSettings.psd1
# Settings for PSScriptAnalyzer invocation.
@{
    Rules = @{
        PSUseCompatibleCommands = @{
            # Turns the rule on
            Enable = $true

            # Lists the PowerShell platforms we want to check compatibility with
            TargetProfiles = @(
                'win-8_x64_10.0.14393.0_6.1.3_x64_4.0.30319.42000_core',
                'win-8_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework',
                'win-8_x64_6.2.9200.0_3.0_x64_4.0.30319.42000_framework'
            )
        }
        PSUseCompatibleSyntax = @{
            # This turns the rule on (setting it to false will turn it off)
            Enable = $true

            # Simply list the targeted versions of PowerShell here
            TargetVersions = @(
                '3.0',
                '5.1',
                '6.2'
            )
        }
    }
}

Now we can run the PSScriptAnalyzer again on the script using the settings file:

Invoke-ScriptAnalyzer -Path ./archiveScript.ps1 -Settings ./PSScriptAnalyzerSettings.psd1

This gives the output:

RuleName                            Severity     ScriptName Line  Message
--------                            --------     ---------- ----  -------
PSUseCompatibleCommands             Warning      archiveScr 1     The parameter 'FullyQualifiedName' is not available for
                                                 ipt.ps1          command 'Import-Module' by default in PowerShell version
                                                                  '3.0' on platform 'Microsoft Windows Server 2012
                                                                  Datacenter'
PSUseCompatibleCommands             Warning      archiveScr 9     The command 'Get-FileHash' is not available by default in
                                                 ipt.ps1          PowerShell version '3.0' on platform 'Microsoft Windows
                                                                  Server 2012 Datacenter'
PSUseCompatibleCommands             Warning      archiveScr 12    The parameter 'LeafBase' is not available for command
                                                 ipt.ps1          'Split-Path' by default in PowerShell version '3.0' on
                                                                  platform 'Microsoft Windows Server 2012 Datacenter'
PSUseCompatibleCommands             Warning      archiveScr 12    The parameter 'LeafBase' is not available for command
                                                 ipt.ps1          'Split-Path' by default in PowerShell version
                                                                  '5.1.17763.316' on platform 'Microsoft Windows Server
                                                                  2019 Datacenter'
PSUseCompatibleCommands             Warning      archiveScr 13    The command 'Compress-Archive' is not available by
                                                 ipt.ps1          default in PowerShell version '3.0' on platform
                                                                  'Microsoft Windows Server 2012 Datacenter'
PSUseCompatibleCommands             Warning      archiveScr 16    The parameter 'NoNewline' is not available for command
                                                 ipt.ps1          'Out-File' by default in PowerShell version '3.0' on
                                                                  platform 'Microsoft Windows Server 2012 Datacenter'
PSUseCompatibleSyntax               Warning      archiveScr 6     The constructor syntax
                                                 ipt.ps1          '[System.Collections.Generic.Dictionary[string,
                                                                  string]]::new()' is not available by default in
                                                                  PowerShell versions 3,4

Now we don’t depend on any variables anymore, and have a separate spefication of the analysis you want. Using this, you could put this into continuous integration environments for example to check that changes in scripts don’t break compatibility.

But what we really want is to know that PowerShell scripts stay compatible as you edit them. That’s what the settings file is building to, and also where it’s easiest to make the changes you need to make your script compatible. For that, we want to integrate with the VSCode PowerShell extension.

Integrating with VSCode for on-the-fly compatibility checking

As explained at the start of this post, VSCode PowerShell extension has builtin support for PSScriptAnalyzer. In fact, as of version 1.12.0, the PowerShell extension ships with PSScriptAnalyzer 1.18, meaning you don’t need to do anything other than create a settings file to do compatibility analysis.

We already have our settings file ready to go from the last step, so all we have to do is point the PowerShell extension to the file in the VSCode settings.

You can open the settings with Ctrl+, (use Cmd instead of Ctrl on macOS). In the Settings view, we want PowerShell > Script Analysis: Settings Path. In the settings.json view this is "powershell.scriptAnalysis.settingsPath". Entering a relative path here will find a settings file in our workspace, so we just put ./PSScriptAnalyzerSettings.psd1:

VSCode settings GUI with PSScriptAnalyzer settings path configured to "./PSScriptAnalyzerSettings.psd1"

In the settings.json view this will look like:

"powershell.scriptAnalysis.settingsPath": "./PSScriptAnalyzerSettings.psd1"

Now, opening the script in VSCode we see “green squigglies” for compatibility warnings:

VSCode window containing script, with green squigglies underneath incompatible code

In the problems pane, you’ll get a full desrciption of all the incompatibilities:

VSCode problems pane, listing and describing identified compatibility issues

Let’s fix the syntax problem first. If you remember, PSScriptAnalyzer supplies a suggested correction to this problem. VSCode integrates with PSScriptAnalyzer’s suggested corrections and can apply them if you click on the lightbulb or with Ctrl+Space when the region is under the cursor:

VSCode suggesting New-Object instead of ::new() syntax

Applying this change, the script is now:

Import-Module -FullyQualifiedName @{ ModuleName = ArchiveHelper; ModuleVersion = '1.1' }

$paths = Get-FoldersToArchive -RootPath 'C:DocumentsDocumentsToArchive'
$archivePath = 'ArchiveServerDocumentArchive'

$hashes = New-Object 'System.Collections.Generic.Dictionary[string,string]'
foreach ($path in $paths)
{
    $hash = (Get-FileHash -LiteralPath $path).Hash
    $hashes[$hash] = $path
    $name = Split-Path -LeafBase $path
    Compress-Archive -LiteralPath $path -DestinationPath (Join-Path $archivePath "$name-$hash.zip")
}

ConvertTo-Json $hashes | Out-File -LiteralPath (Join-Path $archivePath "catalog.json") -NoNewline

The other incompatibilities don’t have corrections; for now PSUseCompatibleCommands knows what commands are available on each platform, but not what to substitute with when a command isn’t available. So we just need to apply some PowerShell knowledge:

  • Instead of Import-Module -FullyQualifiedName @{...} we use Import-Module -Name ... -Version ...;
  • Instead of Get-FileHash, we’re going to need to use .NET directly and write a function;
  • Instead of Split-Path -LeafBase, we can use [System.IO.Path]::GetFileNameWithoutExtension();
  • Instead of Compress-Archive we’ll need to use more .NET methods in a function, and;
  • Instead of Out-File -NoNewline we can use New-Item -Value

We end up with something like this (the specific implementation is unimportant, but we have something that will work in all versions):

Import-Module -Name ArchiveHelper -Version '1.1'

function CompatibleGetFileHash
{
    param(
        [string]
        $LiteralPath
    )

    try
    {
        $hashAlg = [System.Security.Cryptography.SHA256]::Create()
        $file = [System.IO.File]::Open($LiteralPath, 'Open', 'Read')
        $file.Position = 0
        $hashBytes = $hashAlg.ComputeHash($file)
        return [System.BitConverter]::ToString($hashBytes).Replace('-', '')
    }
    finally
    {
        $file.Dispose()
        $hashAlg.Dispose()
    }
}

function CompatibleCompressArchive
{
    param(
        [string]
        $LiteralPath,

        [string]
        $DestinationPath
    )

    if ($PSVersion.Major -le 3)
    {
        # PSUseCompatibleTypes identifies that [System.IO.Compression.ZipFile]
        # isn't available by default in PowerShell 3 and we have to do this.
        # We'll cover that rule in the next blog post.
        Add-Type -AssemblyName System.IO.Compression.FileSystem -ErrorAction Ignore
    }

    [System.IO.Compression.ZipFile]::Create(
        $LiteralPath,
        $DestinationPath,
        'Optimal',
        <# includeBaseDirectory #> $true)
}

$paths = Get-FoldersToArchive -RootPath 'C:DocumentsDocumentsToArchive'
$archivePath = 'ArchiveServerDocumentArchive'

$hashes = New-Object 'System.Collections.Generic.Dictionary[string,string]'
foreach ($path in $paths)
{
    $hash = CompatibleGetFileHash -LiteralPath $path
    $hashes[$hash] = $path
    $name = [System.IO.Path]::GetFileNameWithoutExtension($path)
    CompatibleCompressArchive -LiteralPath $path -DestinationPath (Join-Path $archivePath "$name-$hash.zip")
}

$jsonStr = ConvertTo-Json $hashes
New-Item -Path (Join-Path $archivePath "catalog.json") -Value $jsonStr

You should notice that as you type, VSCode displays new analysis of what you’re writing and the green squigglies drop away. When we’re done we get a clean bill of health for script compatibility:

VSCode window with script and problems pane, with no green squigglies and no problems

This means you’ll now be able to use this script across all the PowerShell versions you need to target. Better, you now have a configuration in your workspace so as you write more scripts, there is continual checking for compatibility. And if your compatibility targets change, all you need to do is change your configuration file in one place to point to your desired targets, at which point you’ll get analysis for your updated target platforms.

Summary

Hopefully in this blog post you got some idea of the new compatibility rules that come with PSScriptAnalyzer 1.18.

We’ve covered how to set up and use the syntax compatibility checking rule, PSUseCompatibleSyntax, and the command checking rule, PSUseCompatibleCommands, both using a hashtable configuration and a settings PSD1 file.

We’ve also looked at using the compatibility rules in with the PowerShell extension for VSCode, where they come by default from version 1.12.0.

If you’ve got the latest release of the PowerShell extension for VSCode (1.12.1), you’ll be able to set your configuration file and instantly get compatibility checking.

In the next blog post, we’ll look at how to use these rules and PSUseCompatibleTypes (which checks if .NET types and static methods are available on target platforms) can be used to help you write scripts that work cross platform across Windows and Linux using both Windows PowerShell and PowerShell Core.


Rob Holt

Software Engineer

PowerShell Team

The post Using PSScriptAnalyzer to check PowerShell version compatibility appeared first on PowerShell.