Tag Archives: PowerShell

Return of the splat!!!

‘Sup PSHomies? How’s it hashin’? 😛

What is a PSHomie pray tell? PSHomie (plural PSHomies) is a term of endearment used amongst PowerShell enthusiasts… Hehe…

Spreading the gospel that is PowerShell! I have my first splat disciple, he goes by the name of Ralf Kervezee. Ralf is an all-around IT guy. He recently took to PowerShell with gusto!!! Go Ralfie!!! We affectionately call him “stuiterbal” which roughly translates to “bouncy ball”. If you meet him in person you’ll understand why.

This meme kinda sums Ralf up:

hey_look_a_squirrel_shirt

Yeah that’s our Ralfie!!! 😉

I’ve been grooming Ralf to do Active Directory Migration based on PowerShell scripts. Now bear in mind Ralf is our “stuiterbal”, he doesn’t ask one question ,he asks five, and while I’m trying to answer the first he’s already moved on to something else. He enjoys figuring things out for himself, which is a good trait. I’ve seen many shamefully request ready-made scripts on the InterNet. If you find a script on the InterNet you should at least test it and know how it works, if you can’t figure it out then maybe you shouldn’t use it eh? Seem fair enough right?

So instead of giving him something ready-made, I gave him a script that helped him figure out how to go about solving his problem. I recently found something on the Net that didn’t work at first but I figured it out, and I must say I ended up appreciating the solution more. Give a man a fish… 😉

We both work at the same company, so we have a mutual CSV Header challenge. There’s a discussion on FB PowerShell group about overengineering your solutions. I’ve been guilty of that as well… Ralf wants to do everything in PowerShell and hey who can blame him? 😉 Ok Ralfie here goes…

First we’ll start with a mock CSV File with users:

#region: csvUsers
$csvUsers =
@"
UserID nieuw,LoginNaam Nieuw,Personeelsnummer,VoorNaam,AchterNaam,Afdeling,Bedrijf, PostCode,StraatNaam,Stad,LocationCode
150131,150131,150131,John,Wayne,IT,Acme,1222 XX,Elmstreet 26,Sciencefiction,1X
150141,150141,150141,Jane,Doe,HR,Acme,1222 XX,Elmstreet 26,Sciencefiction,2X
150211,150211,150211,Jack,Swift,IT,Acme,1222 XX,Elmstreet 26,Sciencefiction,3X
150211,150211,150211,James,Bond,CEO,Acme,0007 XX,Elmstreet 26,Sciencefiction,
"@ |
ConvertFrom-Csv -Delimiter ','
#endregion

Now I usually do my formatting in Excel but to entertain Ralfie, let’s do it in PowerShell, why? Because we can!!!

#region: csvLocation
$csvLocation =
@"
LocationCode,StraatNaam,PostCode,Stad
1X,Elmstreet 26,1666 XX,NightMare
2X,PeterPan 01,0001 ZT,Neverland
3x,Mulan 5, 1111 TK, Disney
"@ |
ConvertFrom-Csv -Delimiter ','

#Group as a hashtable by 'LocationCode'
$lookupLocationCode = $csvLocation | Group-Object -AsHashTable -Property 'LocationCode'
#endregion

Noticed the greyed line (no, not the scrollbar the other grey line)? That’s the key to changing location information. I don’t remember where I found this trick. I do know that Jeff Hicks recently post an article about group-object so I’m guessing it’s probably from Jeff.

And now we need to translate the CSV to something readable by a cmdlet. By the way, I noticed that tab delimiters could be an issue so I used comma this time, that way the example works…

#region: HashTable to translate csv Header
$hshHeader =@{
   'UserID nieuw' = 'SamAccountName'
   Personeelsnummer = 'EmployeeID'
   VoorNaam = 'GivenName'
   AchterNaam = 'SurName'
   Afdeling = 'Department'
   Bedrijf = 'Company'
   PostCode = 'PostalCode'
   StraatNaam = 'StreetAddress'
   Stad = 'City'
}

The hash table will help later on to convert the CSV Header into parameters a cmdlet understands. There’s an up and downside to this approach. The downside is that if the header changes in the csv File you need to update the changes here. no more blackbox effect. The upside, no manual editing. It’s a tradeoff, you decide if it’s worth it…

Here’s the main part. See if you can connect the dots… 😉

#region: Main

#Empty Array to save results
$arrResults = @()

foreach ($user in $csvUsers) {
   $UserProperties = @{}

   foreach ($property in $hshHeader.Keys) {
      $userValue = [string]$user.$property

      #Only add to the hashtable if it has a value otherwise splat will fail
      #You could make the value = $null as an alternative
      if (!([string]::isNullOrEmpty($userValue))) {
         $UserProperties += @{$($hshHeader[$property])=$userValue}
      }
   }

   #Add the hash Key Identity to the table. Identity key value equals SamAccountName
   #You can also remove from the hash table if necessary.
   $UserProperties.Add('Identity', $UserProperties.SamAccountName)

   #Change the current value to the one found in csvLocation
   if (!([string]::isNullOrEmpty($User.'LocationCode'))) {
      $UserProperties['City'] = $lookupLocationCode.$($User.'LocationCode').Stad
      $UserProperties['StreetAddress'] = $lookupLocationCode.$($User.'LocationCode').StraatNaam
      $UserProperties['PostalCode'] = $lookupLocationCode.$($User.'LocationCode').PostCode
   }
   else {
      $UserProperties['City'] = $null
      $UserProperties['StreetAddress'] = $null
      $UserProperties['PostalCode'] = $null
   }

   $arrResults += New-Object PSObject -Property $UserProperties
}
#endregion

And last but not least present new results in Out-GridView

#region: Present results in Out-GridView
$arrResults |
Select-Object EmployeeId,SamAccountName,GivenName,SurName,Department,Company,StreetAddress,PostalCode,City |
Out-GridView -Title "New CSV translated and updated with Location Code - $(Get-Date)"
#endregion

Noticed that James Bond doesn’t have a forwarding Address anymore (because he’s a secret agent and shouldn’t have been listed in the first place!). That’s the kind of fun you can have with PowerShell.

Here’s the full script

#region: csvUsers
$csvUsers =
@"
UserID nieuw,LoginNaam Nieuw,Personeelsnummer,VoorNaam,AchterNaam,Afdeling,Bedrijf, PostCode,StraatNaam,Stad,LocationCode
150131,150131,150131,John,Wayne,IT,Acme,1222 XX,Elmstreet 26,Sciencefiction,1X
150141,150141,150141,Jane,Doe,HR,Acme,1222 XX,Elmstreet 26,Sciencefiction,2X
150211,150211,150211,Jack,Swift,IT,Acme,1222 XX,Elmstreet 26,Sciencefiction,3X
150211,150211,150211,James,Bond,CEO,Acme,0007 XX,Elmstreet 26,Sciencefiction,
"@ |
ConvertFrom-Csv -Delimiter ','
#endregion

#region: csvLocation
$csvLocation = 
@"
LocationCode,StraatNaam,PostCode,Stad
1X,Elmstreet 26,1666 XX,NightMare
2X,PeterPan 01,0001 ZT,Neverland
3x,Mulan 5, 1111 TK, Disney
"@ |
ConvertFrom-Csv -Delimiter ','

#Group as a hashtable by 'LocationCode'
$lookupLocationCode = $csvLocation | Group-Object -AsHashTable -Property 'LocationCode'
#endregion

#region: HashTable to translate csv Header
$hshHeader =@{
   'UserID nieuw' = 'SamAccountName'
   Personeelsnummer = 'EmployeeID'
   VoorNaam = 'GivenName'
   AchterNaam = 'SurName'
   Afdeling = 'Department'
   Bedrijf = 'Company'
   PostCode = 'PostalCode'
   StraatNaam = 'StreetAddress'
   Stad = 'City'
}

#region: Main

#Empty Array to save results
$arrResults = @()

foreach ($user in $csvUsers) {
   $UserProperties = @{}

   foreach ($property in $hshHeader.Keys) {
      $userValue = [string]$user.$property

      #Only add to the hashtable if it has a value otherwise splat will fail
      #You could make the value = $null
      if (!([string]::isNullOrEmpty($userValue))) {
         $UserProperties += @{$($hshHeader[$property])=$userValue}
      }
   }

   #Add the hash Key Identity to the table. Identity key value equals SamAccountName
   #You can also remove from the hash table if necessary
   $UserProperties.Add('Identity', $UserProperties.SamAccountName)

   #Change the current value to the one found in csvLocation
   if (!([string]::isNullOrEmpty($User.'LocationCode'))) {
      $UserProperties['City'] = $lookupLocationCode.$($User.'LocationCode').Stad
      $UserProperties['StreetAddress'] = $lookupLocationCode.$($User.'LocationCode').StraatNaam
      $UserProperties['PostalCode'] = $lookupLocationCode.$($User.'LocationCode').PostCode
   }
   else {
      $UserProperties['City'] = $null
      $UserProperties['StreetAddress'] = $null
      $UserProperties['PostalCode'] = $null
   }

   $arrResults += New-Object PSObject -Property $UserProperties
}
#endregion

#region: Present results in Out-GridView
$arrResults | 
Select-Object EmployeeId,SamAccountName,GivenName,SurName,Department,Company,StreetAddress,PostalCode,City |
Out-GridView -Title "New CSV input updated with Location Code - $(Get-Date)"
#endregion

Well Ralfie there you have it, now it’s you turn to pay it forward…

Hope it’s worth something to you…

Ttyl,

Urv

Advertisements
Welcome!

Welcome!

I’ve recently attended my very first TechEd here in Europe at Barcelona. Just one word, AWESOME!!!

Five days of first hand insight of what Microsoft has in store for us. It was well attended. My main focus at TechEd was:

  • Azure Active Directory
  • SMA & DSC
  • Anything PowerShell related 😉

The 400 levels were well worth it. I didn’t quite figure out the session codes until a colleague pointed out how the system works.

Azure is gaining momentum and Windows 10 is going to be the new Windows 7. I enjoyed the KeyNote Session. There was a dj and everything. Microsoft knows how to make an intro!!! Mark Russinovich deployed WordPress using Dockers. Before the demo many (including myself) didn’t even know about their existence. But if Mark is endorsing Dockers then you know it’s going mainstream… Soon!!!

SMA (Service Management Automation) & DSC (Desired State Configuration) are a match made in heaven. And guess what? QR Codes are a valid option when it comes to MFA (Multi Factored Authentication). I even attended a Machine Learning session. As the Cloud grows it’s going to be a necessity, I’ll get back to you on that…

PowerShell really is at the heart of everything! It isn’t optional! At the PowerShell Summit in Amsterdam, it was all about DSC, now I understand why.

The Mark & Mark session (Mark Minasi & Mark Russinovich) on Cloud Computing was packed!!! Mark Minasi knows how to entertain a crowd.

So much to process… Stay tune, I’ve got a lot to share!!!

Ttyl,

Urv

Here’s a quick impression of TechEd 2014 Europe

The Keynote Session

The Keynote Session

Which booth do you visit first at the TechEd? ;-)

Which booth do you visit first at the TechEd? 😉

Aleksandar Nikolic! He's the admin at powershell.com, standing here with the PowerShell team.

Aleksandar Nikolic! He’s the admin at powershell.com, standing here with the PowerShell team.

Steven Murawski was there too. I even bumped into Jeffrey Snovers and Tobias Weltner!!! It felt like a reunion! :p

Steven Murawski was there too. I even bumped into Jeffrey Snover and Tobias Weltner!!! It felt like a reunion! :p

It dawned on me that my previous blog was all about QR Code encryption. Yes it is possible to create QR codes encrypted. But can you create QR Codes in PowerShell?

As always Google is your friend. Let’s just Google “qr codes generate PowerShell”. Turns out there is a PowerShell script created by Matthew Painter.  Believe it or not the script is 3 years old! It worked like a charm!

Matthew uses Google apis to generate QR Codes (free of charge 😉 ) Best part, you can also do batch processing. Nice!

Here’s the tinyurl to Matthew’s code : http://tinyurl.com/kplw7rm

NEW-QR-psh

And in QR Code… 😉

Matthew sums it up nicely in his Description. There’s just something magical about QR Codes. Kinda like using a metal detector, only you’re hunting for QR Codes.

Have a look at Google apis for more information on QR Code:

Google-API

I think QR Codes could be interesting when it comes to two step verification. And if you could encrypt your QR code… Imagine the possibilities…

Oh I almost forgot, here’s the PowerShell code you can use to generate tinyurls: http://tinyurl.com/khbptb9

Courtesy of PowerShell.com PowerTips.

QR-PowerShellTips-TinyUrl 

Couldn’t help myself…

 Ttyl,

 Urv

 

 

 

 

PowerShell variable names

Ok so this stuck with me from my VBS scripting days and why prefixing variable names can help with debugging your script. It also helps with documenting your script as you go along.

Sure it’s easy to name a variable x,y or z. but your guess is as good as mine as to what kind of data it represents. That’s where prefixes can go a long way…

When scripting in VBS you’d normally add a Prefix to let you know what the object is all about. Here’s a short list of what I use in PowerShell:

 

Type Prefix PowerShell
Array arr $arrMyArray
Hash Table hsh $hshSItes
Collection col $colMyCollrction
PSCustomObject obj $objCurrent
Progress prg $prgProcess
Count cnt $cntUsers
Index idx $idxUsers
Integer int $intQuantity
Boolean bln $blnFound

Here’s an example:

Let’s say your using a hash table. Variable $hshUserProperties let’s me know I’m dealing with a hash table. So I  know what to expect when dealing with $hshUserProperties.

$hshUserProperties = @{
    FirstName = "Irwin"
    SurName = "Strachan"
    Initials = "I.C.A."
}

Now let’s say I was dealing with a [PSCustomObject] (Powershell v3) I’d use the Prefix “obj” to let me know this is a custom PowerShell object.

$objUserProperties = [PSCustomObject]@{
    FirstName = "Irwin"
    SurName = "Strachan"
    Initials = "I.C.A."
}

It might seem trivial now but trust me, when debugging your scripts it helps!

When you want to collect an array of objects just add

$colUsersInformation += $objUserProperties

and your good to go!

I’ll admit that the whole custom object was new to me at the beginning, so it took some getting use to.

Which isn’t to say it’s necessary to create a custom object ahead of time.You have the choice of either adding the custom object or making the hash table an object in the process:

$colUsersInformation += New-Object PSObject -Property $hshUserProperties

this will also get the job done. $hshUserProperties still helps out by letting me know that it’s a hash table and I need to do something with it “before” adding it to a collection.

Ok and now about the name

When defining your variable name, my preference goes to CamelCase. Sure you could follow it to the letter. My prefix always is in smallcase so my variable name starts each word with a Capital letter. $hshUserProperties is a hash table containing User Properties value.

It helps to give your variable a name that will help you decipher what it’s all about. And with the help of PowerShell_ISE tab completion, having longer variable names shouldn’t be an issue…

Well that my tip for defining sound PowerShell variable names…

Hope it’s worth something to you…

Ttyl,

Urv