Tag: PowerShell

Automating delimiter selection when working with Csv cmdlets

Recently I walked passed a collegue with an error on his Powershell console which peaked my interest. He quickly noted that he had chosen the wrong delimiter for the Csv he imported which resulted in errors in the code, I then jokingly said ”Why don’t you just use the ‘Get-CsvDelimiter’ cmdlet?” and we had a quick laugh.
30 minutes later the ”Get-CsvDelimiter” function was born, but first,

Let’s dive into how Import-Csv, ConvertFrom-Csv & delimiters really work

When used correctly Import-Csv & ConvertFrom-Csv creates an array object with each row as a PSCustomObject with named content based on headers.

Import-Csv has two constructors, one with Path as a required and the other with Path & Delimiter as required.
If you omit the delimiter parameter the Path constructor will be used, now this constructor has a required parameter (according to the documentation) that is auto filled. Instead of using Delimiter we can use ”UseCulture” which takes the current culture delimiter as input,

”To find the list separator for a culture, use the following command: (Get-Culture).TextInfo.ListSeparator.” –docs.microsoft

If we interpret the documentation this is a required parameter, but it is not really required, as we are able to pass only the -Path parameter and delimiter will autofill

Assume we’re using the following CSV as input ($File)

the command ”Import-Csv $File” will output a valid object. Now in my opinion it should fail. As my culture specifies semicolon (;) as the default listseparator, while forcing ”-UseCulture” can’t produce a correct csv object. This basically means that UseCulture is not a required parameter and the default unless specified is always a comma (,)

The exact same goes for ConvertFrom-Csv.

Presenting Get-CsvDelimiter

The below function will search and find the most probable delimiter used in a Csv file.

Let’s see how it works.

$File is a csv file with the below data.

If we run Import-Csv $File we’ll get a incorrect table object, every row will have a single property containing the row data.

If we instead specify a delimiter as shown below, we’ll calculate the most probable delimiter and use that to produce a correct CSV table object without having to inspect the csv culture or assume anything.

And to prove it works, the below code outputs only the Name column in the Csv

If we have a stringobject and need to convert it that is also possible.

With this method we can use virtually any delimiter we want, assuming that the Csv is formatted correctly. Again we’re using the same csv input but we change the delimiter to a ”greater than” (>) symbol and see how the function performs.

Now when we run the function standalone we’ll get a Greater than symbol as the return

And finally, when running the previous code we get the same output as when we were using a semicolon as the delimiter.

 

Get-CsvDelimiter



Mapped network printers unavailable due to SMB1 being obsolete

INTRODUCTION

As we all might be familiar with, printers are one of those little peculiar matters within IT. Implementing these in an IT-environment is self-explanatory oftentimes, but when they do not cooperate the issue itself can stem from one single obscure root cause, if not a string of these having to be checked upon.

Recently, I encountered a particular printer issue which I found interesting enough to share. The root cause here, in summary, was due to the network protocol SMB1 (Server Message Block) being obsolete in recent Windows releases.



Monitoring vDisk Rebalance Enabled

In a recent use-case that I stumbled across, I wanted to monitor a few different things in a Citrix-environment with Provisioning Services technology.

In this specific blog-post I’ll show you how I configured monitoring for whether Rebalance Enabled is configured for active vDisk, with Provisioning Services (PVS) Powershell SnapIn.



Monitoring vDisk Replication

In a recent use-case that I stumbled across, I wanted to monitor a few different things in a Citrix-environment with Provisioning Services technology.

In this specific blog-post I’ll show you how I configured monitoring of vDisk Replication with Provisioning Services (PVS) Powershell SnapIn.



Datetime and RFC3339 compliance in powershell – a deepdive

A collegue of mine asked if there is a way to output a RFC compliant datetime (https://www.ietf.org/rfc/rfc3339.txt) in powershell without manually formatting in T and Z in the middle and end to comply with ISO standard and imply UTC +-00:00

 

Before i start with the how, I’d like to address the why.

If you’ve ever done some coding you’re sure to have encountered issues with datettime and possibly errors and incidents due to the timeformat of a datetime string.
For example, if I live in the US then time is commonly written in month-day-year format, which during the first 12 days of each month is indistinguishable from the european day-month-year format.
This is also encountered in code, for example in powershell my locale is Swedish and the ”Get-Date” cmdlet returns ”den 1 augusti 2018 16:35:24” which is easy and readable for a human.
However if i convert it to a string it becomes in US format even though my culture settings in powershell is set to swedish.
In my opinion this behavior is wrong as I expect to be given a ISO standard universal format, or at least a culture appropriate format. Instead I am given a US format.

With that said, developing automation and tools for global customers a standard format is much needed when we write to logs.

The How

After a short time on google it seems no one had done this properly in powershell. I also found out that XML is RFC compliant.

How did i do it?

Returns:

Great! Now let’s put it into some real code.

Example 1: Writing current date into a logfile

The output becomes a RFC compliant string and gets stored in the $now variable to be used into a out-file log operation.

Example 2: Writing a job deadline datettime

Here we create a datettime object, add 20 hours and then convert it to a RFC compliant datettime string and store it into the $RFCDeadline variable.

Hope this helps someone!



Automate tasks with use of XenServer Powershell Module

Working with backups of your virtual machines is obviously essential. Working with exports in XenServer can some times be time consuming, particularly with bigger virtual disks attached to your virtual machine. In this scenario I will show you an alternative to manually export via XenCenter, by doing it with Powershell to an remote server using XenServer Powershell module.



Use PowerShell & Windows Update to force drivers to be downloaded from the Internet in a Task Sequence

Working with client driver packages for me is related to a never-ending story. Drivers are frequently being updated and results in manually handling updates of Driver Packages in Configuration Manager. But since some computer manufacturers are releasing updates through Windows Update, so we thought; What if you can use a Task Sequence to force Windows Update to look for updates and drivers over the Internet instead of using manually handled Driver Packages? So I decided to try with a Surface Book.

With help from the PowerShell Module PSWindowsUpdate, created by Michal Gajda (downloaded from TechNet), and with a post from Waingrositblog, I had all the necessary bits forcing a Surface Book to download drivers from Windows Update, over the Internet, while running a Task Sequence. I started by modifying the steps, created by Waingrositblog, in the Task Sequence steps a bit. I found having one step running a PowerShell script instead of three steps, two of which was running cmd lines, more suitable.

This image illustrates the Task Sequence step.

I added the update step just after applying Windows- and Network Settings, where we usually apply driver packages.

The RPS (Run PowerShell) – Microsoft Update step is running the following script:

To verify the success of the script I went through the WindowsUpdateLog.Log and found that during the Task Sequence, a lot of drivers were installed. Here I would like to use PCI drivers as an example. As shown in the image below, the WindowsUpdateLog successfully downloaded and applied the drivers.

This is the WindowsUpdateLog.Log generated after successfully running the Update Drivers sequence.

I also tried the running the Task Sequence without the Windows Update / Driver script and found out the device had conflicts with the PCI drivers. These drivers is just used as an example in this process, there are several conflicts and other drivers missing as shown in the image below.

This image illustrates conflicts with, among others, the PCI drivers after not running the Update Drivers sequence.

This image illustrates when the drivers are applied.

As shown in these images, the Install Driver step running in the Task Sequence finds the correct and necessary drivers. After a Task Sequence successfully has gone through no exclamation marks are found in the Device Manager.

Some computer manufacturers are using Windows Update as a secondary source for updates, and because of this some drivers can be out of date. This is a reason why the Surface is a great example of using Windows Update for drivers since Microsoft release their updates, up to date.

If you have any questions, opinions or improvements, feel free to email me at Johan.Nilsson@Xenit.se



Sending CSS formatted tables in Outlook

If you’ve ever used Powershell to send HTML tables in Outlook containing CSS you’ve probably been disappointed of the outcome.
There is some archived documentation for Outlook 2007 that is still viable for Outlook 365 (https://msdn.microsoft.com/en-us/library/aa338201(v=office.12).aspx).

Basically the function accepts a csv and css file, hardcodes the css into the table and outputs a formatted HTML table that is compatible with Outlook.

Example table sent using the function and send-mailmessage
The css has odd/even for readability, bolded column 1/4 and red text for column 3.
This is by default impossible to achieve using just css in outlook.

Commandline

HTML output

CSS

Since the CSS does not work perfectly the style.css file imported needs some specific configuration..

  • classes has some specific name structure”
    • columns are named .coln
      • n is the number of the column starting with 1 to infinity. .col1 .col2 and so on
    • one whitespace is required between class name and the curlybrackets.
      • Curlybrackets must be on the same row as class name
      • Ending curlybrackets must be on a separate line
    • Data must be on separate rows
  • Odd/even css is the only tr handled code.
    • Must be named exactly
      • tbody tr:nth-child(odd) {
      • tbody tr:nth-child(even) {

Example style.CSS

Function

 



Azure Automation – Running scripts locally on VM through runbooks

I was tasked to create a powershell script to run on a schedule on a Azure VM. Normally this would be running as a scheduled task on the VM but seeing as we’re working with AzureVM and schedule tasks are legacy I wanted to explore the possibilities of running the schedule and script in Azure to keep the VM clean and the configuration scalable.

After some research the best option would be running the powershell script as a CustomScriptExtension on the VM, and the schedule would be handled by a Process Automation Runbook (using Automation Accounts).

What I ended up with is the script below. It’s fairly easy to configure and contains almost all the required configuration in the parameters.



Recursively search Azure Ad group members

When working with on-premise Active Directory an administrator often has to recursively search AD groups, this is easy using the ActiveDirectory module with cmdlet ”Get-AdGroupMember <Group> -Recusive”.
For the AzureAD equivalent this is no longer an option, the cmdlet Get-AzureADGroupMember has three parameters.

PARAMETERS
-All <Boolean>
If true, return all group members. If false, return the number of objects specified by the Top parameter
-ObjectId <String>
Specifies the ID of a group in Azure AD.
-Top <Int32>
Specifies the maximum number of records to return.