Coffee Break | Windows PowerShell and Piping


The | (pipe) functionality in Windows PowerShell offers endless opportunities for formatting and manipulating results from one cmdlet to the next.

Coffee Break 4: Piping in Windows PowerShell

 Each time we run a Windows PowerShell cmdlet, the resulting output is not text but an Object providing structured information of the result.

Example:  Get-NAVServerInstance will return existing instances of NAVServerInstance Objects:

with the following properties:

  •   ServerInstance
  •   DisplayName
  •   State
  •   ServiceAccount
  •   Version
  •   Default

Windows PowerShell can pipe objects. Pipelines are a series of cmdlets (segments) separated by a Pipeline character ‘|’. Each Item is passed through all segments of the pipeline (left to right) before the next is processed.

Piping example:

First import your Dynamics NAV cmdlets (if you are not already in the Microsoft Dynamics NAV Administration Shell, that is):

Import-Module ‘C:\Program Files\Microsoft Dynamics NAV\80\Service\Microsoft.Dynamics.Nav.Management.dll’

This imports the NAV.Management.dll for version 80 (=NAV 2015). Adjust the path to the version you are working with.

Get-NAVServerInstance

In case Get-NAVServerInstance returns more than one, then let’s filter the one(s) that we want by piping the original result through a filter. Or said in other words: We pipe it to the Where-Object cmdlet:

#Filter by version

Get-NAVServerInstance | where-Object –Property Version -like “8.0*”

One can also omit the –Property parameter here, and just run:

Get-NAVServerInstance | where-Object Version -like “8.0*”

 

Then we will take the result and pipe that to another cmdlet, let’s pipe it to Sync-NAVTenant:

Get-NAVServerInstance | where-Object –Property Version -like “8.0*” | Sync-NAVTenant

Note also that the syntax of Where-Object cmdlet has changed across Windows PowerShell  versions, so for compatibility, and going forward , the following syntax should be used:

Get-NAVServerInstance | where-Object  {$_.Version -like “8.0*”} | Sync-NAVTenant

Where $_ is used to reference the Item returned by the previous pipeline segment (in the above example, it references the instance of NavServerInstance Object returned by Get-NAVServerInstance cmdlet). However running the above will still fail to sync Microsoft Dynamics NAV tenants for instances that are not running (State: stopped).  This will not abort the process, but we can also further filter on only those instances that are running:

Get-NAVServerInstance | where-Object  {$_.Version -like “8.0*”} | where-Object {$_.State –eq ‘Running’} | Sync-NAVTenant

The two pipline segments filtering the output can of course be combined in one. We join the filtering conditions using –And operator. Note that Logical operators (-And / -Or) are valid only within script blocks.

Get-NAVServerInstance | where-Object  {$_.Version -like “8.0*” -And $_.State –eq ‘Running’} | Sync-NAVTenant

 

See further content about Piping here: https://technet.microsoft.com/en-us/library/dd347655.aspx

 

Jasminka Thunes, Escalation Engineer Dynamics NAV EMEA

Lars Lohndorf-Larsen, Escalation Engineer Dynamics NAV EMEA

Comments (2)

  1. Mads says:

    As a PS beginner it is great with these posts – thanks.

    Is it possible to pipe Get-NavTenant and Get-NAVServerSession in an multitenant environment?

    I would like to see if there is an active serversession on any tenant.

  2. Thanks for the comment MadsAssuming the prerequisites above (imported modules)

    For Dynamics NAV 2015:

    for specific service – it's quite straightforward:

    get-NAVTenant <servicename> | get-NAVServerSession

    To run accross all middle tiers on the server:

    get-NAVserverinstance|get-navtenant|get-navServerSession

    To run accross all middle tiers on the server, and retrieve Win Client sessions only (for ex):

    get-NAVserverinstance| get-navtenant | get-navserversession | where-object {$_.ClientType -eq 'WindowsClient'}