Monthly Archive

Categories

PowerShell v5

PowerShell version

Discovering the PowerShell version you’re using can be an interesting task.

The automatic variable $PSVersionTable was introduced in PowerShell v2. On my Windows 10 version 1803 machine for Windows PowerShell I get

PS> $PSVersionTable

Name Value
---- -----
PSVersion 5.1.17134.48
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.17134.48
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1

 

$PSVersionTable is a hashtable so the order in which items are displayed may vary. The contents of the hashtable have changed over time as well.

 

The important parts of $PsversionTable include:

The version of PowerShell itself

PS> $PSVersionTable.PSVersion

Major Minor Build Revision
----- ----- ----- --------
5 1 17134 48

PS> $PSVersionTable.PSVersion.Major
5

This a simple test for version.

 

The edition is also important

PS> $PSVersionTable.PSEdition
Desktop

Desktop means its full CLR – in other words Windows PowerShell

 

The WSMAN version is also important

PS> $PSVersionTable.WSManStackVersion

Major Minor Build Revision
----- ----- ----- --------
3 0 -1 -1

You need v3 to use CIM sessions.

 

With PowerShell v6 you get a few more options

PS> $PSVersionTable

Name Value
---- -----
PSVersion 6.0.1
PSEdition Core
GitCommitId v6.0.1
OS Microsoft Windows 10.0.17134
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0

 

Notice PSEdition is set to Core.

The OS and Platform data are v6 only

The PSRemotingProtocolVersion, SerializationVersion and WSManStackVersion are the same for Windows PowerShell v5.1 and PowerShell v6.

 

PowerShell v6 runs on Windows, Linux and macOS. You can test which OS you’re on from $PSVersionTable or more simply using the following automatic variables:

PS> ls variable:\is*

Name Value
---- -----
IsLinux False
IsMacOS False
IsWindows True
IsCoreCLR True

Using these you could create branching logic to perform a task by calling the appropriate command based on the underlying operating system.

Controlled zip

Powershell v5 introduced the Compress- and Expand-Archive cmdlets which enabled you to manage compressed archives. I had a question about how you could control adding files to archives using a CSV file. This is how you do a controlled zip.

 

Start by creating a set of test data.

1..100 |
foreach {
$file = "File$psitem.txt"
Get-Process | Out-File -FilePath $file

$i = Get-Random -Minimum 1 -Maximum 4
$zip = "Archive$i.zip"

$props = @{
FileName = $file
Archive = $zip
}

New-Object -TypeName PSObject -Property $props
} | Export-Csv -Path FilesToArchive.CSV –NoTypeInformation

 

I created a 100 files – name of the form FileN.txt and into each piped the output of Get-Process just so they weren’t empty.

I wanted 3 zip files – named ArchiveN.zip

I used Get-Random to assign the zip file.

Create an object to with the file and archive and output to CSV

 

The CSV looks like this:

FileName Archive
-------- -------
File1.txt Archive1.zip
File2.txt Archive3.zip
File3.txt Archive1.zip
File4.txt Archive2.zip
File5.txt Archive1.zip
File6.txt Archive3.zip

 

To perform the zip

Import-Csv .\FilesToArchive.CSV |
foreach {
Compress-Archive -Path $_.FileName -DestinationPath $_.Archive -Update
}

 

Read the CSV file and for each file add it to the appropriate archive. The –Update parameter on Compress-Archive is what allows you to add files to an existing archive.

Clear-RecycleBin

Every so often I find a new cmdlet in PowerShell. This was the case with Clear-RecycleBin that I’ve just found.

It appears to have been introduced with PowerShell 5.0 BUT isn’t available in PowerShell 6.0

With pretty simple syntax

PS> Get-Command Clear-RecycleBin -Syntax

Clear-RecycleBin [[-DriveLetter] <string[]>] [-Force] [-WhatIf] [-Confirm] [<CommonParameters>]

Its easy to use

PS> Clear-RecycleBin -DriveLetter C -Force

use –Force to avoid the question to confirm the action

Updating built in modules

Windows 10 and Server 2016 automatically install a module called Pester which is used for testing code. Its the foundation of Test Driven Development or Behaviour Driven Development using PowerShell.

The version  installed by default is 3.4.0.

Pester is originally an open source module that has been incorporated into Windows. The latest version from the PowerShell Gallery is 4.0.2

Normally you’d use Update-Module to install the new version BUT you didn’t install pester from the gallery using Install-Module so you’ll get a big fat error message.

The answer is to use

Install-Module pester –Force

You might still get an error message about the Pester module not being catalog signed. if you do and still want the latest version then use

Install-Module pester -Force -SkipPublisherCheck

PowerShell classes

I’ve just had an article on PowerShell classes published on the UK TechNet bog - https://blogs.technet.microsoft.com/uktechnet/2016/09/29/powershell-classes/

Update-Help errors

One the latest build of Windows 10 – 14296 I’m getting errors when updating help. Three modules don’t seem to have help available

 

Update-Help : Failed to update Help for the module(s) 'Microsoft.PowerShell.Operation.Validation'
with UI culture(s) {en-GB} : The value of the HelpInfoUri key in the module manifest must resolve to
a container or root URL on a website where the help files are stored. The HelpInfoUri
'https://www.msn.com/en-gb/?ocid=NEFLS000' does not resolve to a container.
At line:1 char:1
+ Update-Help -Force
+ ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Update-Help], Exception
    + FullyQualifiedErrorId : InvalidHelpInfoUri,Microsoft.PowerShell.Commands.UpdateHelpCommand

 

Update-Help : Failed to update Help for the module(s) 'PSScriptAnalyzer' with UI culture(s) {en-US}
: The Help content at the specified location is not valid. Specify a location that contains valid
Help Content.
At line:1 char:1
+ Update-Help -Force
+ ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Update-Help], Exception
    + FullyQualifiedErrorId : HelpContentXmlValidationFailure,Microsoft.PowerShell.Commands.UpdateHe
   lpCommand

 

Update-Help : Failed to update Help for the module(s) 'SecureBoot' with UI culture(s) {en-GB} :
Unable to retrieve the HelpInfo XML file for UI culture en-GB. Make sure the HelpInfoUri property in
the module manifest is valid or check your network connection and then try the command again.
At line:1 char:1
+ Update-Help -Force
+ ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (:) [Update-Help], Exception
    + FullyQualifiedErrorId : UnableToRetrieveHelpInfoXml,Microsoft.PowerShell.Commands.UpdateHelpCo
   mmand

 

I’ve checked and the help isn’t available for en-US culture.

Unregistering the default repository–PS version dependent?

In this post - https://richardspowershellblog.wordpress.com/2016/09/17/powershell-repositories/ – I stated that you could unregister the default PowerShell repository.

 

I also said that the statement in the documentation for Unregister-PSrepository that you couldn’t unregister PSGallery was incorrect.

 

A couple of readers have left comments stating that they tried it and got an error message stating that PSGallery can’t be unregistered.

 

I did my first test on Windows 10 latest preview build – build 14926

PS> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.14926.1000
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.14926.1000
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

 

I’ve just test on Windows Server 2016 TP5

PS C:\Windows\system32> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.14300.1000
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
CLRVersion                     4.0.30319.42000
BuildVersion                   10.0.14300.1000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

 

The version of PowerShell 5.1 on Server 2016 TP5 doesn’t have the –Default parameter on Register-PSrepositiry but this works

Register-PSRepository -Name PSGallery -SourceLocation https://www.powershellgallery.com/api/v2/

 

It appears that the ability to unregister the default repository and then re-register it is an evolving feature in PowerShell 5.1

PowerShell repositories

A reader on my blog asked if you can unregister the default PowerShell repository so you just use an internal repository.

 

First off – PSGallery is the default repository

PS> Get-PSRepository | Format-List

Name                      : PSGallery
SourceLocation            : https://www.powershellgallery.com/api/v2/
Trusted                   : False
Registered                : True
InstallationPolicy        : Untrusted
PackageManagementProvider : NuGet
PublishLocation           : https://www.powershellgallery.com/api/v2/package/
ScriptSourceLocation      : https://www.powershellgallery.com/api/v2/items/psscript/
ScriptPublishLocation     : https://www.powershellgallery.com/api/v2/package/
ProviderOptions           : {}

 

According to the documentation for Unregister-PSRepository you CAN’T unregister the default repository. In fact you can – the documentation appears to be incorrect

 

You can unregister PSGallery  with

Get-PSRepository -Name PSGallery | Unregister-PSRepository

NOTE You have to do this on a user by user basis

 

If you decide you need the default repository again then you can register it like this:

Register-PSRepository –Default

.psd1 files

.psd1 files are usually used as module manifests

You can test the manifest

PS>  Test-ModuleManifest -Path 'C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0\Pester.psd1' | fl

Name              : Pester
Path              : C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0\Pester.psd1
Description       : Pester provides a framework for running BDD style Tests to execute and validate PowerShell commands inside of PowerShell and offers a powerful set of Mocking Functions that allow tests to mimic and mock the  functionality of any command inside of a piece of powershell code being tested. Pester tests can execute any command or script that is accesible to a pester test file. This can include functions, Cmdlets,  Modules and scripts. Pester can be run in ad hoc style in a console or it can be integrated into the Build scripts of a Continuous Integration system.
ModuleType        : Script
Version           : 3.4.0
NestedModules     : {}
ExportedFunctions : {Describe, Context, It, Should...}
ExportedCmdlets   :
ExportedVariables : {Path, TagFilter, ExcludeTagFilter, TestNameFilter...}
ExportedAliases   :

 

or you can view the whole output

 

PS>  Test-ModuleManifest -Path 'C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0\Pester.psd1' | fl *

LogPipelineExecutionDetails : False
Name                        : Pester
Path                        : C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0\Pester.psd1
ImplementingAssembly        :
Definition                  :
Description       : Pester provides a framework for running BDD style Tests to execute and validate PowerShell commands inside of PowerShell and offers a powerful set of Mocking Functions that allow tests to mimic and mock the  functionality of any command inside of a piece of powershell code being tested. Pester tests can execute any command or script that is accesible to a pester test file. This can include functions, Cmdlets,  Modules and scripts. Pester can be run in ad hoc style in a console or it can be integrated into the Build scripts of a Continuous Integration system.
Guid                        : a699dea5-2c73-4616-a270-1f7abb777e71
HelpInfoUri                 :
ModuleBase                  : C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0
PrivateData                 : {PSData}
Tags                        : {powershell, unit testing, bdd, tdd...}
ProjectUri                  : https://github.com/Pester/Pester
IconUri                     : http://pesterbdd.com/images/Pester.png
LicenseUri                  : http://www.apache.org/licenses/LICENSE-2.0.html
ReleaseNotes                :
RepositorySourceLocation    :
Version                     : 3.4.0
ModuleType                  : Script
Author                      : Pester Team
AccessMode                  : ReadWrite
ClrVersion                  :
CompanyName                 : Pester
Copyright                   : Copyright (c) 2016 by Pester Team, licensed under Apache 2.0 License.
DotNetFrameworkVersion      :
ExportedFunctions           : {[Describe, Describe], [Context, Context], [It, It], [Should, Should]...}
Prefix                      :
ExportedCmdlets             : {}
ExportedCommands            : {[Describe, Describe], [Context, Context], [It, It], [Should, Should]...}
FileList                    : {}
CompatiblePSEditions        : {}
ModuleList                  : {}
NestedModules               : {}
PowerShellHostName          :
PowerShellHostVersion       :
PowerShellVersion           : 2.0
ProcessorArchitecture       : None
Scripts                     : {}
RequiredAssemblies          : {}
RequiredModules             : {}
RootModule                  : Pester.psm1
ExportedVariables           : {[Path, ], [TagFilter, ], [ExcludeTagFilter, ], [TestNameFilter, ]...}
ExportedAliases             : {}
ExportedWorkflows           : {}
ExportedDscResources        : {}
SessionState                :
OnRemove                    :
ExportedFormatFiles         : {}
ExportedTypeFiles           : {}

 

You can also import the contents of the .psd1 file

PS>  Import-PowerShellDataFile -Path 'C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0\Pester.psd1'

Name                           Value                                                                                          
----                           -----                                                                                          
Copyright                      Copyright (c) 2016 by Pester Team, licensed under Apache 2.0 License.                          
ModuleToProcess                Pester.psm1                                                                                    
PrivateData                    {PSData}                                                                                       
PowerShellVersion              2.0                                                                                            
CompanyName                    Pester                                                                                         
GUID                           a699dea5-2c73-4616-a270-1f7abb777e71                                                           
Author                         Pester Team                                                                                    
FunctionsToExport              {Describe, Context, It, Should...}                                                             
VariablesToExport              {Path, TagFilter, ExcludeTagFilter, TestNameFilter...}                                         
Description                    Pester provides a framework for running BDD style Tests to execute and validate PowerShell co...
ModuleVersion                  3.4.0 

 

which in some ways is more useful as you can easily see what is actually in the manifets rather than dealing with a lot of empty properties.

 

You can create .psd1 files to hold other data and read them with Import-PowerShellDataFile. Default parameters for your favourite cmdlets is one thing that comes to mind

Get-ComputerInfo

One of the new items in PowerShell 5.1 is the Get-ComputerInfo cmdlet

PS>  Get-Command Get-ComputerInfo -Syntax

Get-ComputerInfo [[-Property] <string[]>] [<CommonParameters>]

 

PS>  Get-ComputerInfo

WindowsBuildLabEx                                       : 14393.0.amd64fre.rs1_release.160715-1616
WindowsCurrentVersion                                   : 6.3
WindowsEditionId                                        : Professional
WindowsInstallationType                                 : Client
WindowsInstallDateFromRegistry                          : 19/07/2016 12:27:55
WindowsProductId                                        : XXXXXXXXXXXXXXXXXXXX
WindowsProductName                                      : Windows 10 Pro
WindowsRegisteredOrganization                           :
WindowsRegisteredOwner                                  : XXXXXXXXXXXXXXXXXXXX

WindowsSystemRoot                                       : C:\WINDOWS
BiosCharacteristics                                     : {7, 11, 12, 15...}
BiosBIOSVersion                                         : {OEMA - 1072009, 2.05.0250, American
                                                          Megatrends - 4028E}
BiosBuildNumber                                         :
BiosCaption                                             : 2.05.0250
BiosCodeSet                                             :
BiosCurrentLanguage                                     : en|US|iso8859-1
BiosDescription                                         : 2.05.0250
BiosEmbeddedControllerMajorVersion                      : 255
BiosEmbeddedControllerMinorVersion                      : 255
BiosFirmwareType                                        : Uefi
BiosIdentificationCode                                  :
BiosInstallableLanguages                                : 1
BiosInstallDate                                         :
BiosLanguageEdition                                     :
BiosListOfLanguages                                     : {en|US|iso8859-1}
BiosManufacturer                                        : American Megatrends Inc.
BiosName                                                : 2.05.0250
BiosOtherTargetOS                                       :
BiosPrimaryBIOS                                         : True
BiosReleaseDate                                         : 10/04/2015 01:00:00
BiosSeralNumber                                         : 036685734653
BiosSMBIOSBIOSVersion                                   : 2.05.0250
BiosSMBIOSMajorVersion                                  : 2
BiosSMBIOSMinorVersion                                  : 7
BiosSMBIOSPresent                                       : True
BiosSoftwareElementState                                : Running
BiosStatus                                              : OK
BiosSystemBiosMajorVersion                              : 2
BiosSystemBiosMinorVersion                              : 5
BiosTargetOperatingSystem                               : 0
BiosVersion                                             : OEMA - 1072009
CsAdminPasswordStatus                                   : Unknown
CsAutomaticManagedPagefile                              : True
CsAutomaticResetBootOption                              : True
CsAutomaticResetCapability                              : True
CsBootOptionOnLimit                                     :
CsBootOptionOnWatchDog                                  :
CsBootROMSupported                                      : True
CsBootStatus                                            : {0, 0, 0, 0...}
CsBootupState                                           : Normal boot
CsCaption                                               : RSSURFACEPRO2
CsChassisBootupState                                    : Safe
CsChassisSKUNumber                                      : Surface_Pro_2
CsCurrentTimeZone                                       : 60
CsDaylightInEffect                                      : True
CsDescription                                           : AT/AT COMPATIBLE
CsDNSHostName                                           : RSsurfacePro2
CsDomain                                                : WORKGROUP
CsDomainRole                                            : StandaloneWorkstation
CsEnableDaylightSavingsTime                             : True
CsFrontPanelResetStatus                                 : Unknown
CsHypervisorPresent                                     : False
CsInfraredSupported                                     : False
CsInitialLoadInfo                                       :
CsInstallDate                                           :
CsKeyboardPasswordStatus                                : Unknown
CsLastLoadInfo                                          :
CsManufacturer                                          : Microsoft Corporation
CsModel                                                 : Surface Pro 2
CsName                                                  : RSSURFACEPRO2
CsNetworkAdapters                                       : {USB Ethernet, WiFi, Bluetooth Network
                                                          Connection}
CsNetworkServerModeEnabled                              : True
CsNumberOfLogicalProcessors                             : 4
CsNumberOfProcessors                                    : 1
CsProcessors                                            : {Intel(R) Core(TM) i5-4200U CPU @ 1.60GHz}
CsOEMStringArray                                        : {EU}
CsPartOfDomain                                          : False
CsPauseAfterReset                                       : -1
CsPCSystemType                                          : Mobile
CsPCSystemTypeEx                                        : Slate
CsPowerManagementCapabilities                           :
CsPowerManagementSupported                              :
CsPowerOnPasswordStatus                                 : Unknown
CsPowerState                                            : Unknown
CsPowerSupplyState                                      : Safe
CsPrimaryOwnerContact                                   :
CsPrimaryOwnerName                                      : XXXXXXXXXXXXXXXXXXXX
CsResetCapability                                       : Other
CsResetCount                                            : -1
CsResetLimit                                            : -1
CsRoles                                                 : {LM_Workstation, LM_Server, NT,
                                                          Potential_Browser...}
CsStatus                                                : OK
CsSupportContactDescription                             :
CsSystemFamily                                          : Surface
CsSystemSKUNumber                                       : Surface_Pro_2
CsSystemType                                            : x64-based PC
CsThermalState                                          : Safe
CsTotalPhysicalMemory                                   : 8506093568
CsPhyicallyInstalledMemory                              : 8388608
CsUserName                                              : RSsurfacePro2\Richard
CsWakeUpType                                            : PowerSwitch
CsWorkgroup                                             : WORKGROUP
OsName                                                  : Microsoft Windows 10 Pro
OsType                                                  : WINNT
OsOperatingSystemSKU                                    : 48
OsVersion                                               : 10.0.14393
OsCSDVersion                                            :
OsBuildNumber                                           : 14393
OsHotFixes                                              : {KB3176927}
OsBootDevice                                            : \Device\HarddiskVolume2
OsSystemDevice                                          : \Device\HarddiskVolume4
OsSystemDirectory                                       : C:\WINDOWS\system32
OsSystemDrive                                           : C:
OsWindowsDirectory                                      : C:\WINDOWS
OsCountryCode                                           : 44
OsCurrentTimeZone                                       : 60
OsLocaleID                                              : 0809
OsLocale                                                : en-GB
OsLocalDateTime                                         : 28/07/2016 14:30:32
OsLastBootUpTime                                        : 27/07/2016 09:02:45
OsUptime                                                : 1.05:27:47.0631253
OsBuildType                                             : Multiprocessor Free
OsCodeSet                                               : 1252
OsDataExecutionPreventionAvailable                      : True
OsDataExecutionPrevention32BitApplications              : True
OsDataExecutionPreventionDrivers                        : True
OsDataExecutionPreventionSupportPolicy                  : OptIn
OsDebug                                                 : False
OsDistributed                                           : False
OsEncryptionLevel                                       : 256
OsForegroundApplicationBoost                            : Maximum
OsTotalVisibleMemorySize                                : 8306732
OsFreePhysicalMemory                                    : 5530384
OsTotalVirtualMemorySize                                : 9617452
OsFreeVirtualMemory                                     : 6525292
OsInUseVirtualMemory                                    : 3092160
OsTotalSwapSpaceSize                                    :
OsSizeStoredInPagingFiles                               : 1310720
OsFreeSpaceInPagingFiles                                : 1274160
OsPagingFiles                                           : {C:\pagefile.sys}
OsHardwareAbstractionLayer                              : 10.0.14393.0
OsInstallDate                                           : 19/07/2016 13:27:55
OsManufacturer                                          : Microsoft Corporation
OsMaxNumberOfProcesses                                  : 4294967295
OsMaxProcessMemorySize                                  : 137438953344
OsMuiLanguages                                          : {en-GB}
OsNumberOfLicensedUsers                                 :
OsNumberOfProcesses                                     : 77
OsNumberOfUsers                                         : 2
OsOrganization                                          :
OsArchitecture                                          : 64-bit
OsLanguage                                              : en-GB
OsProductSuites                                         : {TerminalServicesSingleSession}
OsOtherTypeDescription                                  :
OsPAEEnabled                                            :
OsPortableOperatingSystem                               : False
OsPrimary                                               : True
OsProductType                                           : WorkStation
OsRegisteredUser                                        : XXXXXXXXXXXXXXXXXXXX
OsSerialNumber                                          : 00330-80000-00000-AA844
OsServicePackMajorVersion                               : 0
OsServicePackMinorVersion                               : 0
OsStatus                                                : OK
OsSuites                                                : {TerminalServices,
                                                          TerminalServicesSingleSession}
OsServerLevel                                           :
KeyboardLayout                                          : en-GB
TimeZone                                                : (UTC+00:00) Dublin, Edinburgh, Lisbon,
                                                          London
LogonServer                                             : \\RSSURFACEPRO2
PowerPlatformRole                                       : Slate
HyperVisorPresent                                       : False
HyperVRequirementDataExecutionPreventionAvailable       : True
HyperVRequirementSecondLevelAddressTranslation          : True
HyperVRequirementVirtualizationFirmwareEnabled          : True
HyperVRequirementVMMonitorModeExtensions                : True
DeviceGuardSmartStatus                                  : Off
DeviceGuardRequiredSecurityProperties                   :
DeviceGuardAvailableSecurityProperties                  :
DeviceGuardSecurityServicesConfigured                   :
DeviceGuardSecurityServicesRunning                      :
DeviceGuardCodeIntegrityPolicyEnforcementStatus         :
DeviceGuardUserModeCodeIntegrityPolicyEnforcementStatus :

 

You can use the –Property parameter to restrict output

PS>  Get-ComputerInfo -Property OsArchitecture, OsUptime

OsArchitecture OsUptime
-------------- --------
64-bit         1.05:34:53.9424271

 

Wild cards are allowed so this works and lists all properties starting with OS

Get-ComputerInfo -Property Os*

 

Looking at the output it seems to be a collection of properties from a number of CIM classes. Might be fun to track down what comes from where one rainy day