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

Advertisements
Posted in Powershell | 3 Comments

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

Posted in Powershell | Leave a comment

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.

Posted in PowerShell v6 | Leave a comment

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.

Posted in DevOps | 1 Comment

PowerShell v6.2 preview 1

PowerShell v6.2 preview 1 quietly appeared yesterday – https://github.com/PowerShell/PowerShell/releases

No major breaking changes.

New features include:

  • Type accelerators for unsigned integers
  • Support for cd+
  • Test-ModuleManifest update to correctly populate nested modules
  • Set-Service –status stopped will also stop dependencies

 

The Test-Connection and –workingdirectory issues are still unresolved.

There’s nothing earth shattering in the updates but that seems to be the name of the game with PowerShell v6 – lots of small incremental changes

Posted in PowerShell v6 | Leave a comment

PowerShell v6.1 working directory

PowerShell v6.1 introduced a very annoying change in that a –workingdirectory parameter was added to pwsh.exe. When you install v6.1 working directory is automatically set to ~ which is your home folder. The workingdirectory doesn’t play nice with your profile. In my profile I set the location to C:\scripts where I keep my work in progress and scripts I use on a frequent basis. If –workingdirectory is set to ~ my profile is ignored depending on whether I’m running as administrator (profile is honoured) or not. This is how I got round the annoyance of the PowerShell v6.1 working directory.

This is for WINDOWS only. If you’re on Linux or mac you’ll need to adapt this as appropriate.

First option is to go in and edit the icon – Right click the PowerShell icon on start menu. Select More –> Open file location. Select the PowerShell shortcut, right click and select Properties. Edit the working  directory parameter. Either remove is and the folder or change the folder.

So that’s manual and painful. Unfortunately, there isn’t any functionality in PowerShell to manage short cuts. There is a way using COM objects.

function get-icon {

$wsshell = New-Object -ComObject ‘WScript.Shell’

$icon = $wsshell.CreateShortcut(‘C:\ProgramData\Microsoft\Windows\Start Menu\Programs\PowerShell\PowerShell 6 (x64).lnk’)

$icon

}

Create an instance of the WScript.Shell COM object. Notice you have to use the CreateShortcut method to get the shortcut properties!

The important line in the output is

Arguments        : -WorkingDirectory C:\Scripts

You can clear the arguments

function clear-argument {

$wsshell = New-Object -ComObject ‘WScript.Shell’

$icon = $wsshell.CreateShortcut(‘C:\ProgramData\Microsoft\Windows\Start Menu\Programs\PowerShell\PowerShell 6 (x64).lnk’)

$icon.Arguments = ”

$icon.Save()

}

Ideally, I suppose you should just remove the –workingdirectory  argument but quick and dirty works for me on this.

If you don’t have a –workingdirectory parameter set your profile isn’t honoured with regard to setting locations unless you run as administrator.

To set the working directory

function set-argument {

$wsshell = New-Object -ComObject ‘WScript.Shell’

$icon = $wsshell.CreateShortcut(‘C:\ProgramData\Microsoft\Windows\Start Menu\Programs\PowerShell\PowerShell 6 (x64).lnk’)

$icon.Arguments = ‘-WorkingDirectory C:\Scripts’

$icon.Save()

}

If you change the argument in this manner you may need to recreate any icons you pinned to the start bar.

Posted in PowerShell v6 | Leave a comment

PowerShell approved verbs

PowerShell uses a verb-noun style for naming cmdlets. The list of Powershell approved verbs is available at https://docs.microsoft.com/en-us/powershell/developer/cmdlet/approved-verbs-for-windows-powershell-commands.

You should use the approved verbs when writing functions or cmdlets. Import-Module will complain about using unapproved verbs.

You can also see the list of approved verbs using Get-Verb.

There’s also a set of verb naming rules that are meant for you to follow. Some are good ideas like not using the reserved verbs – others such as dictating the use of Pascal syntax I ignore because I prefer to use lower case for function names. It helps me remember which is my code! If I was publishing to the gallery I’d probably conform but as I tend to write proof of concept code more than anything I want to keep a visual separation.

The other very useful set information are the synonyms for verbs that you shouldn’t use. For instance don’t use Append, Attach, Concatenate or Insert – use Add. Some of this information is contextual though as you shouldn’t use Pop or Out as a synonym for Exit BUT Pop is perfectly valid when removing an item off a stack (Pop-Location is the only cmdlet I know of that works in that way).

Posted in Powershell | 1 Comment