Monthly Archive

Categories

Monthly Archives: January 2018

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

Documentation can be wrong!

We rely on vendor documentation to help us solve problems. Documentation is produced by people and people make mistakes so Documentation can be wrong!

 

As an example:

The CIM class Win32_OperatingSystem has a Description property. According to the documentation the Description property is

“ Description of the Windows operating system. Some user interfaces for example, those that allow editing of this description, limit its length to 48 characters.”

 

if you take this to mean the description describes something about the OS you’d be wrong.

PS> Get-CimInstance Win32_OperatingSystem | Format-List Caption, Description

Caption : Microsoft Windows 10 Enterprise
Description : Richards Laptop

 

The caption property gives a description of the OS. The Description property is what you’ll find at

Control Panel –> System –> Advanced system settings –> Computer Name tab –> Computer description field

 

If you find something that doesn’t match with the documentation double check as you may find the documentation is wrong!

PowerShell sleep

PowerShell use tends to be very interactive. You run a command at the console and get some results. You run a script and get some results. How do you make PowerShell sleep?

There’s a few ways you can make PowerShell code sleep.

 

First there’s Start-Sleep

PS> for ($i=0; $i -le 10; $i++){
>> if ($i -eq 5) {
>> Get-Date
>> Start-Sleep -Seconds 30
>> Get-Date
>> }
>> }

30 January 2018 14:06:21
30 January 2018 14:06:51

I use Start-Sleep when starting a bunch of virtual machines to ensure one is fully up and running before attempting to start the next.

 

You can use the pause function to add a manually controlled delay

PS> for ($i=0; $i -le 10; $i++){
>> if ($i -eq 5) {
>> Get-Date
>> pause
>> Get-Date
>> }
>> }

30 January 2018 14:08:57
Press Enter to continue...:
30 January 2018 14:09:44

 

Pause is a function created when you start PowerShell

PS> Get-Command pause | select definition

Definition
----------
$null = Read-Host 'Press Enter to continue...'

so if you prefer you can use Read-Host

 

You could also use a workflow and suspend the job

PS> workflow w1 {
>> for ($i=0; $i -le 10; $i++){
>> if ($i -eq 5) {
>> Get-Date
>> Suspend-Workflow
>> Get-Date
>> }
>> }
>> }
PS> w1 -AsJob

Id Name PSJobTypeName   State HasMoreData  Location  Command
-- ---- -------------   ----- -----------  --------  -------
3  Job3 PSWorkflowJob Running        True  localhost      w1

PS> Get-Job

Id Name PSJobTypeName     State HasMoreData  Location Command
-- ---- -------------     ----- -----------  -------- -------
3  Job3 PSWorkflowJob Suspended        True localhost      w1


PS> Resume-Job -Id 3

Id Name PSJobTypeName   State HasMoreData  Location Command
-- ---- -------------   ----- -----------  -------- -------
3  Job3 PSWorkflowJob Running        True localhost      w1


PS> Get-Job

Id Name PSJobTypeName     State HasMoreData  Location Command
-- ---- -------------     ----- -----------  -------- -------
3  Job3 PSWorkflowJob Completed        True localhost      w1


PS> Receive-Job -Id 3

30 January 2018 18:39:25
30 January 2018 18:40:39

 

Remember that workflows aren’t available on PowerShell v6

PowerShell –f string

A PowerShell –f string is used to format the data inside a string. –f is usually referred to as the format operator.

 

The operation of the format operator is best explained by examples. At its simplest you create fields in the string using {} and the arguments to the right of the –f operator are assigned to those fields in numeric order:

PS> "{0} is  {1}" –f  'A', 'a'
A is  a

 

‘A’ is the first argument (so is assigned to field {0} and so on.

 

You can format the contents of the fields. The full syntax is

{index[,alignment][:format string]}

index is the zero based index of the arguments after the format operator as you’ve seen.

alignment takes a positive number and aligns the item to the right of a field of that length. A negative number produces a left alignment.

PS> "{0,5} is  {1,5}!" -f 'A', 'a'
A is      a!
PS> "{0,-5} is  {1,5}!" -f 'A', 'a'
A     is      a!
PS> "{0,5} is  {1,-5}!" -f 'A', 'a'
A is  a    !
PS> "{0,-5} is  {1,-5}!" -f 'A', 'a'
A     is  a    !

 

The format strings cover numeric and date time formatting

https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings

https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings

will get you started and provide links to other formatting information

 

A few more examples.

To control the total number of digits displayed

PS> "{0:D3} {1:D3} {2:D3}" -f 2, 20, 200
002 020 200

 

for hexadecimal – case matches case in string

PS> "{0:X4} {1:x8} " -f  1234, 1234
04D2 000004d2

 

Truncating the digits after decimal point

PS> "{0:F3} {1:F2} {2:F1}" -f 2.1234, 3.1234, 4.1234
2.123 3.12 4.1

 

Dates can be manipulated as well

PS> "{0:yyyy} {0:MM} {0:dd} {0:hh} {0:mm} {0:ss}" -f (Get-Date)
2018 01 28 02 24 03

Note that I’m referring to a single object for all of the fields

DSC update

The PowerShell team have posted an update on what’s happening with DSC. https://blogs.msdn.microsoft.com/powershell/2018/01/26/dsc-planning-update-january-2018/

 

The interesting thing is the decoupling of the Local Configuration Manager from Windows. A new LCM that can use resources written in multiple languages sounds good – DSC on Linux can finally have custom written resources.

 

LCM will be open source

 

No comments on pull server in the post though – ideally pull server should be open source as well

PowerShell v6.0.1

PowerShell v6.0.1 is available from https://github.com/PowerShell/PowerShell/releases

 

This release upgrades PowerShell to use .NET core v2.0.5 which addresses a couple of security vulnerabilities. The release also addresses upgrade issues on some Linux distributions due to version numbers being misunderstood.

 

Also available is the v1.0.0 beta for OpenSSH https://github.com/PowerShell/Win32-OpenSSH/releases. This version supplies one of my wishes for 2018 in that the installation and configuration is much simpler

Iron Scripter prequels

One of the new things for Summit 2018 is the iron Scripter competition on the last afternoon. As a warm up for the competition we’re running a number of Iron Scripter prequels.

 

A puzzle will be published every week – first 2 are on powershell.org.

 

A forum exists to discuss the solutions in the context of the Iron Scripter factions.

 

Even if you aren’t going to Summit you can solve the puzzles and contribute to the solution.

 

Think of the puzzles as a Scripting Games lite. We provide a commentary on the puzzle including an example solution but we DON’T grade any submissions.

 

Join in and enjoy.

PowerShell v6 GA and beyond

PowerShell v6 achieved General Availability on 10 January 2018. https://blogs.msdn.microsoft.com/powershell/2018/01/10/powershell-core-6-0-generally-available-ga-and-supported/

 

Why do these things always happen when I’m in a plane over the Atlantic?

 

GA is a tremendous milestone but its not the end by any means. Work has already begun on v6.1

https://blogs.msdn.microsoft.com/powershell/2018/01/24/powershell-core-6-1-roadmap/

 

Note a service release at the end of January to use .NET core 2.05

V6.1 looks to be planned for about 6 months from now with some interesting features.

Just the date

Way back in this post https://richardspowershellblog.wordpress.com/2008/03/27/start-and-end-of-week/ I showed how to find the start of the week. I recently had a question about how to restrict the display to just the date.

 

PowerShell uses the .NET datetime class for working with dates so there will always be time information even if its set to 0. You can however restrict the display to just the date information

 

The ToShortDateString and ToLongDateString methods will give you just the date information but as a string

PS> $s = Get-Date -Hour 0 -Minute 0 -Second 0
PS> $d = $s.AddDays(-($s).DayOfWeek.value__)
PS> $d.ToShortDateString()
07/01/2018
PS> $d.ToLongDateString()
07 January 2018

 

Alternately you could create a custom format using the formatting strings found at

https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings

For example

PS> Get-Date -Date $d -Format "yyyy-MM-dd gg"
2018-01-07 A.D.

 

You could combine the code lines to give

PS> $s = Get-Date -Hour 0 -Minute 0 -Second 0
PS> Get-Date -Date ($s.AddDays(-($s).DayOfWeek.Value__)) -Format "yyyy-MM-dd gg"
2018-01-07 A.D.

 

If you do this often enough then create a function

Relevance of Scripts

I had a sudden thought today about the relevance of scripts – PowerShell Scripts -  today.

 

PowerShell v6 can’t run some of the modules that we’ve come to rely on – for instance the AD cmdlets. The Windows Compatibility Pack (see previous post) enables access to some of the underlying .NET classes that enable AD administration through PowerShell.

 

This means going back to the v1/v2 days and writing scripts – we may wrap them as advanced functions and modules these days but the basic code is the same – instead of using canned cmdlets.

 

My first two books

PowerShell in Practice - https://www.manning.com/books/powershell-in-practice

and

PowerShell and WMI - https://www.manning.com/books/powershell-and-wmi

 

supply lots of code examples for working with PowerShell Scripts including AD and WMI. If you haven’t got a copy they’ll help you get back to basics.