Monthly Archive

Categories

Reverse an array

Ever needed to reverse an array?

If its sorted then sorting in the opposite direction will work. Most arrays aren’t sorted so you need to use the Reverse static method of the array class

 

Here’s some examples

$carray = 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'
$carray -join ','
[array]::Reverse($carray)
$carray -join ','

 

$iarray = 1,2,3,4,5,6,8,9,10
"$iarray"
[array]::Reverse($iarray)
"$iarray"

 

$psa = Get-Process p*
$psa
[array]::Reverse($psa)
$psa

 

The thing to note is that the array is reversed rather than creating output so if you do this

$iarray = 1,2,3,4,5,6,8,9,10
$newary = [array]::Reverse($iarray)

$iarray is reversed and $newary is empty!

 

If you need the original and reversed arrays take a copy of the original and then reverse one of them.

Hyper-V book now available

My Hyper-V book now available.

 

Ebook direct from the publisher: https://www.apress.com/gb/book/9781484241158#otherversion=9781484241165

 

The Kindle version is on Amazon UK:

https://www.amazon.co.uk/s/ref=nb_sb_noss_2?url=search-alias%3Daps&field-keywords=hyper-v+2019&rh=i%3Aaps%2Ck%3Ahyper-v+2019

Presumably other Amazon sites will follow soon

 

The paper back version is on pre-order from Apress and Amazon to be available on 25 December 2018 – Happy Christmas

Finding the minimum and maximum values

Finding the minimum and maximum values in a set of numbers is ridiculously easy with PowerShell.

I’ve created a function in line with the other techniques I’ve shown but in reality could be be done equally well as a single line of code:

function get-minmax {
[CmdletBinding()]
param (
[int[]]$iarray
)

$mm = $iarray | Measure-Object -Minimum -Maximum

New-Object -TypeName PSobject -Property @{
Minimum = $mm.Minimum
Maximum = $mm.Maximum
}
}

 

Just pipe the array into Measure-Object and use the –Minimum and –Maximum parameters as shown. I created an output object for easier handling if you want to do anything else to the array.

 

You can also get the sum and average of the array with Measure-Object. PowerShell v6.1 adds the Standard Deviation and an –Allstats parameter so you don’t need to specify each individual option:

PS> $iarray = 1,2,3,4,23,5,6,7,8,9,10,23,11,12,13,7,14,15,16,17,18,20,21,22,11,23,24,25
PS> $iarray | Measure-Object -AllStats

Count : 28
Average : 13.2142857142857
Sum : 370
Maximum : 25
Minimum : 1
StandardDeviation : 7.46030057411125
Property :

Windows 10 install wasting my time

I’ve just made the mistake of installing Windows 10 Insider preview build 18272 from the iso. The only thing I can say is that Windows 10 install wasting my time.

 

The install proceeds as you would expect but then once the basic OS installation is complete it crawls, at the speed of a overloaded truck with no engine, through a whole series of questions about settings.

 

If Windows got out of my way and let me perform the settings changes they’d have been done in a few minutes instead the windows install wasted the best part of 30 minutes taking me through its ridiculous setup dialog.

 

What’s worse is that its the Enterprise edition I was installing!

 

Microsoft please get out of my way and let me make changes. Every edition of Windows since Vista has made it harder and harder to actually make changes. The continuously changing settings menus mean that the settings you need are buried further and further under meaningless dialogs and when you do get the bottom you’re often using the old control panel!

 

The continuous feature update promised by Windows 10 is failing because its actually getting harder to do things. Contrary to your belief Microsoft you don’t know better than me how I want my machines configured – you’re applying a blanket best guess set of settings that are becoming more difficult to unravel.

Find a missing integer–alternative solution

In my recent post about finding a missing integer in an array of numbers I didn’t spell out the assumptions. In this post I’ll explain those assumptions and show you how to Find a missing integer–alternative solution.

The assumptions were:

The sequence of numbers in the array starts at 1

The values increment by 1

 

If the sequence doesn’t start at 1 the technique fails as the expected sum being n(n+1)/2 breaks down.

As an alternative you can calculate the expected sum by finding the average of the numbers in the sequence and multiplying by the number of expected entries in the sequence.

function get-missinginteger {
[CmdletBinding()]
param (
[int[]]$iarray,

[int]$expectedlength
)

#$expectedSum = ($expectedlength * ($expectedlength + 1) ) / 2

# don't know if array is in numeric order
$sarray = $iarray | sort

$expectedSum = $expectedlength * (($sarray[0] + $sarray[-1]) / 2)

$actualsum = 0
foreach ($n in $iarray) {
$actualsum += $n
}

$missingnumber = $expectedSum - $actualsum
$missingnumber
}

 

I’ve changed the function name. The only other change is to sort the array and calculate the expected sum using the average

$sarray = $iarray | sort
$expectedSum = $expectedlength * (($sarray[0] + $sarray[-1]) / 2)

 

The examples from the previous post work as does

PS> $iarray = 6,7,8,9,10,11,12,13,14,15,16,17,18,20,21,22,23,24,25

get-missinginteger -iarray $iarray -expectedlength 20

19

Finding and removing duplicates

Continuing the thoughts about techniques for dealing with integer arrays – this is how to go about finding and removing duplicates from the array.

First – to find any duplicates use Group-Object

function get-duplicate {
[CmdletBinding()]
param (
[int[]]$iarray
)

$iarray | Group-Object |
where Count -gt 1 |
foreach {
New-Object -TypeName PSobject -Property @{
DuplicateNumber = $_.Name
Count = $_.Count
}
}
}

 

If the count is greater than 1 it means you have duplicates so create an output object and display the integer value and the total number of occurrences.

 

Removing duplicates is a bit more tricky

function remove-duplicate {
[CmdletBinding()]
param (
[int[]]$iarray
)

$dupcount =@{}

$duplicates = get-duplicate -iarray $iarray

$dedup = $iarray | foreach {
if ($_ -in $duplicates.DuplicateNumber) {
if ( -not $dupcount["$_"]) {
$dupcount += @{"$_" = 1 }
$psitem
}
}
else {
$psitem
}
}

$dedup
}

 

Get the duplicates as before. Iterate over the input array. If the value is found in $duplicates.DuplicateNumber – your using the object property as a property of the array to effectively get an array of the duplicate values – test to see if its in the $dupcount hashtable. If it isn’t add an entry to the hashtable and output the value. If it is in $dupcount do nothing and therefore skip that value.

 

If the value isn’t in $duplicates.DuplicateNumber emit the value.

 

You’ll notice that any values output by the foreach cmdlet go straight into $dedup array – this builds that array automatically and is the most efficient way to get the values into the array.

 

Final step is to output the de-duplicated array.

Find a missing integer

I stumbled across a set of programmer interview questions recently. They raised some interesting problems that I thought would be fun to show a PowerShell answer. This is the first of them – find a missing integer in an array.

Consider an array of integers. It should have 10 members:

$iarray = 1,2,3,4,5,6,7,8,9,10

 

But what if one is missing

$iarray = 1,2,3,4,5,6,8,9,10

In this case the number 7 is missing.

 

This problem assumes that there is a regular increment between members of the array – in this case 1. In mathematical terms its a series.

function get-missingnumber {
[CmdletBinding()]
param (
[int[]]$iarray,

[int]$expectedlength
)

$expectedSum = ($expectedlength * ($expectedlength + 1) ) / 2

$actualsum = 0
foreach ($n in $iarray) {
$actualsum += $n
}

$missingnumber = $expectedSum - $actualsum
$missingnumber
}

 

The solution is to find the expected sum of the series which is found using

(n * (n + 1)) / 2

where n is the expected length of the series. 1 is the increment between members of the series. You can generalise this for any increment but that’s left as an exercise for you.

 

Then calculate the actual sum by looping through the array and summing the values.

 

The missing number is the difference between the expected sum and the actual sum

 

Here’s some examples

PS> ## 10 integers - number 7 missing
PS> $iarray = 1,2,3,4,5,6,8,9,10
PS> get-missingnumber -iarray $iarray -expectedlength 10
7

PS> ## 25 integers - number 19 missing
PS> $iarray = 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,21,22,23,24,25

PS> get-missingnumber -iarray $iarray -expectedlength 25
19

 

A quick way to generate the array to play with:

PS> $r = Get-Random -Maximum 26 -Minimum 1
PS> $iarray = 1..25 | where {$psitem -ne $r}
PS> get-missingnumber -iarray $iarray -expectedlength 25
22
PS> $r
22

Managing errors

If you try to do a directory listing through C:\Windows\system32 you’ll get some access denied errors. I’m going to show you how to do this while managing errors that arise. The code will also highlight a few of the PowerShell error handling techniques.

 

$epath2 = $null

Get-ChildItem -Path C:\Windows\System32 -Recurse -Force -Directory -ErrorVariable epath2 |
foreach {
if ($?) {
Out-File -InputObject $_.FullName -FilePath c:\test\paths.txt -Append
}
}

if ($epath2) {
$epath2 |
foreach {
($_.Exception -split "'")[1] | Out-File -FilePath c:\test\errors.txt -Append
}
}

 

Set $epath2 to $null to clear any data.

 

Use -ErrorVariable epath2 to define the variable into which errors are directed.

 

Get-ChildItem will recurse through the folder structure – use –Directory to ignore files.

 

In the foreach statement check $? which holds True or False depending on if last statement succeeded. Append the full path to the folder to the paths.txt file.

 

If $epath2 has a value then iterate over the values splitting out the folder paths from the error statement. Write to errors.txt

Test-Connection cmdlet

The Test-Connection cmdlet wasn’t included in PowerShell v6.0 but did make a come back in v6.1.

 

The v6.1 version of Test-Connection has some serious issues as I’ve described before.

 

Work is being done at the moment to remedy those issues – hopefully for v6.2

 

This is your chance to comment on a cmdlet and help determine how it will work.

 

The issues to comment on are:

https://github.com/PowerShell/PowerShell/issues/7685

https://github.com/PowerShell/PowerShell/issues/6557

 

PowerShell v6 is community driven.  This is an opportunity to help drive the PowerShell you want to see.

DevOps team structures

DevOps has never really excited me and I never understood why until I read about DevOps team structures - https://web.devopstopologies.com/

The article suggests 7 bad practices or ‘anti-types:

  1. Dev and Ops Silos
  2. DevOps Team Silo
  3. Dev doesn’t need Ops
  4. DevOps as tools team
  5. Rebranded administrators
  6. Ops embedded in dev team
  7. Dev and DBA silos

 

It then looks at some team structures that can be made to work

  1. Dev and Ops collaboration
  2. Fully Shared Ops responsibilities
  3. Ops as Infrastructure as a Service
  4. DevOps as external service
  5. DevOps team with expiry date
  6. DevOps evangelist team
  7. Site Reliability Engineering team
  8. Container driven collaboration
  9. Dev and DBA collaboration

 

One thing that’s often not explicitly mentioned when discussing DevOps is the need for whatever teams, and individuals, to communicate. This is often anathema in my experience and why a DevOps type approach is so badly needed.

 

As to why DevOps hasn’t excited me – the article made me realise I’d spent a good part of my working life moving between Dev & Ops and often occupying the middle, grey area that DevOps makes its own. Its what I’ve been doing for a long time mainly without the tools we have today and not viewing it as anything special – just getting the job done.