Tag: Administration

  • How-to stop auto-login to Business Central On-prem with Windows Auth

    authentication

    Probably quite an unusual scenario.. so I’ll explain why it came up!

    A retail customer using LS Central wants to use their POS machine for both POS and back office functionality.

    The complication is; the POS (Web Client) needs to automatically login with the POS Windows account (the signed in Windows account) but for back office tasks they want the user to log in with their own AD accounts.

    The first thing that comes to mind is NavUserPassword for the BO users right? Well, the users are setup in AD so makes sense to use this rather than adding extra overhead of maintaining users/passwords in two places, plus they already have infrastructure in place using Windows auth. UserName auth? Sounds like it should work but again will require additional BC service and as the POS machine is on the domain and we’re using the Web Client it doesn’t really fit the brief:

    UserName – With this setting, the user is prompted for username/password credentials when they access Business Central. These credentials are then validated against Windows authentication by Business Central Server. There must already be a corresponding user in Windows. Security certificates are required to protect the passing of credentials across a wide-area network. Typically, this setting should be used when the Business Central Server computer is part of an authenticating Active Directory domain, but the computer where the Dynamics NAV Client connected to Business Central is installed is not part of the domain.


    So anyway, to cut a long story short you can disable passthrough Windows authentication in Chromium based web browsers (Chrome and Edge) by emptying the authentication server whitelist. This is done by adding a command line switch: –auth-server-whitelist=”_”

    In this case this meant creating a new button called Backoffice in LS Start to open Chrome and adding the –auth-server-whitelist switch to the parameter list along with the BC url.

    disable auto logon
    Of course, you can also add this command line switch to a Windows shortcut:

    auth server whitelist

    You’ll notice this will disable passthrough authentication for the open browser window, the problem is if you open another link in Chrome/Edge by default it will open it in the same window. To get around this we’ll need to add another command line switch to force Chrome/Edge to open this link in its own window: –new-window

    If you want to learn more about Chromium command line switches, have a browse over here: List of Chromium Command Line Switches « Peter Beverloo

    Job done.

  • How-to: Run LS Central in a Docker container – Part 2

    Docker containers

    In my previous blog post How-to: Run LS Central in a Docker container I showed how you can run LS Central on Docker with some manual steps to get the client and server components installed.

    For this blog post I’m going to show a more reusable solution where you can install the client components via a script passed into the container.

    To make the Business Central Docker images configurable, the designers decided to incorporate a set of Powershell script files which can be substituted at build time to override the standard setup process. The standard scripts are found in the containers C:\Run directory:

    Business Central container run contents
    The AdditionalSetup.ps1 script file, which is empty by default, when overwritten will execute after the main setup has completed. This is where we can provide code to install additional components such as client and service add-ins.

    When you place a script with the same name into the containers C:\Run\my directory, Docker will use this version of the file instead of the standard version. As we saw in my previous blog post the New-NavContainer Cmdlet’s -myScripts parameter is used to copy files from the Docker host into the containers C:\Run\my directory.

    I’ve created an AdditionalSetup.ps1 file with the following content:

    Write-Host "Installing LS Client Components.."
    
    & "C:\Run\my\LS Central 13.04.00.852 Client Components.exe" /silent
    
    Write-Host "Installing LS Service Components.."
    
    & "C:\Run\my\LS Central 13.04.00.852 Service Components.exe" /silent
    
    Write-Host "Remove database backup.."
    
    Remove-Item -Path 'C:\Run\my\*' -Include *.bak

    Note: The reason I’m not cleaning up the installer files is because I was getting an access denied error. If anyone knows why I can delete the database backup but not the .exe files please let me know in the comments!

    For this example I’ve created a folder on the Docker host machine with the following content:

    LS Central install files

     

     

     

     

    Now I can run a script to build the container, using my setup files and additional setup script:

    $imageName = "mcr.microsoft.com/businesscentral/onprem:1810-cu3"
    $navcredential = New-Object System.Management.Automation.PSCredential -argumentList "admin", (ConvertTo-SecureString -String "admin" -AsPlainText -Force)
    New-NavContainer -accept_eula `
                        -containerName "LSDEMO2" `
                        -Auth NavUserPassword `
                        -imageName $imageName `
                        -Credential $navcredential `
                        -licenseFile "C:\Temp\LS\BC13License.flf" `
                        -updateHosts `
                        -alwaysPull `
                        -additionalParameters @('--env bakfile="c:\run\my\w1-ls-central-13-04-release.bak"') `
                        -myScripts @(`
                                    "C:\Temp\LS\w1-ls-central-13-04-release.bak", `
                                    "C:\Temp\LS\LS Central 13.04.00.852 Client Components.exe", `
                                    "C:\Temp\LS\LS Central 13.04.00.852 Service Components.exe", `
                                    "C:\Temp\LS\AdditionalSetup.ps1"`
                                    ) `
                        -memoryLimit 8GB `
                        -accept_outdated `
                        -doNotExportObjectsToText
  • How-to: Run LS Central in a Docker container

    Microsoft have been releasing Business Central (formerly Dynamics NAV) as Docker images for a few years now. These have been great for testing and learning the new developer tools and trying out new functionality, but in real life many of us don’t use vanilla Business Central. You, like me, probably need an ISV solution and it’s demo data before Docker is useful on customer projects and demos.

    This blog post shows one way you can get LS Central by LS Retail running in a Docker container.

    LS Central releases contain a demo .bak file which we’ll use to replace the default .bak file that comes with Business Central. We’ll also need the client and server add-in files to deploy to the container.

    Note it’s important that any installer packages can run in unattended/silent mode as Windows Server Core based containers do not have a GUI to handle any user interaction. One way to check this is to run the .exe with the /? parameter and see if it prints out any information. LS Central installers use the /silent parameter:

    PS C:\Temp\LS> & '.\LS Central 13.04.00.852 Client Components.exe' /?
    
    ---------------------------
    Setup
    ---------------------------
    The Setup program accepts optional command line parameters.
    
    
    /HELP, /?
    
    Shows this information.
    
    /SP-
    
    Disables the This will install... Do you wish to continue? prompt at the beginning of Setup.
    
    /SILENT, /VERYSILENT
    
    Instructs Setup to be silent or very silent.
    
    /SUPPRESSMSGBOXES
    
    Instructs Setup to suppress message boxes.
    
    /LOG
    
    Causes Setup to create a log file in the user's TEMP directory.
    
    /LOG="filename"
    
    Same as /LOG, except it allows you to specify a fixed path/filename to use for the log file.
    
    /NOCANCEL
    
    Prevents the user from cancelling during the installation process.
    
    /NORESTART
    
    Prevents Setup from restarting the system following a successful installation, or after a Preparing to Install failure that requests a restart.
    
    /RESTARTEXITCODE=exit code
    
    Specifies a custom exit code that Setup is to return when the system needs to be restarted.
    
    /CLOSEAPPLICATIONS
    
    Instructs Setup to close applications using files that need to be updated.
    
    /NOCLOSEAPPLICATIONS
    
    Prevents Setup from closing applications using files that need to be updated.
    
    /RESTARTAPPLICATIONS
    
    Instructs Setup to restart applications.
    
    /NORESTARTAPPLICATIONS
    
    Prevents Setup from restarting applications.
    
    /LOADINF="filename"
    
    Instructs Setup to load the settings from the specified file after having checked the command line.
    
    /SAVEINF="filename"
    
    Instructs Setup to save installation settings to the specified file.
    
    /LANG=language
    
    Specifies the internal name of the language to use.
    
    /DIR="x:\dirname"
    
    Overrides the default directory name.
    
    /GROUP="folder name"
    
    Overrides the default folder name.
    
    /NOICONS
    
    Instructs Setup to initially check the Don't create a Start Menu folder check box.
    
    /TYPE=type name
    
    Overrides the default setup type.
    
    /COMPONENTS="comma separated list of component names"
    
    Overrides the default component settings.
    
    /TASKS="comma separated list of task names"
    
    Specifies a list of tasks that should be initially selected.
    
    /MERGETASKS="comma separated list of task names"
    
    Like the /TASKS parameter, except the specified tasks will be merged with the set of tasks that would have otherwise been selected by default.
    
    /PASSWORD=password
    
    Specifies the password to use.
    
    
    For more detailed information, please visit http://www.jrsoftware.org/ishelp/index.php?topic=setupcmdline
    ---------------------------
    OK   
    ---------------------------
    
    

    Of course if the installer is only adding DLLs to the add-ins folder then you could also get these files from another machine and copy them into the container. Have a look at the docker cp command documentation to see how to copy files into a container.

    We’re going to use the Create-NavContainer Cmdlet from the NavContainerHelper PowerShell module to build the container and use the LS demo database. We can use the -myScripts parameter to copy the LS components into the container, and then install them individually using the shell desktop shortcut the NavContainerHelper module creates.

    I used a script from Freddy’s Blog and adapted to suit. The steps look like this, adjust as required:

    $imageName = "mcr.microsoft.com/businesscentral/onprem:cu3"
    $navcredential = New-Object System.Management.Automation.PSCredential -argumentList "admin", (ConvertTo-SecureString -String "admin" -AsPlainText -Force)
    New-NavContainer -accept_eula `
    -containerName "LSDEMO" `
    -Auth NavUserPassword `
    -imageName $imageName `
    -Credential $navcredential `
    -licenseFile "https://www.dropbox.com/<blanked out>/Licence.flf?dl=1" `
    -myScripts @("C:\Temp\LS\w1-ls-central-13-04-release.bak", "C:\Temp\LS\LS Central 13.04.00.852 Client Components.exe", "C:\Temp\LS\LS Central 13.04.00.852 Service Components.exe") `
    -additionalParameters @('--env bakfile="c:\run\my\w1-ls-central-13-04-release.bak"') `
    -useBestContainerOS `
    -includeCSide `
    -updateHosts `
    -enableSymbolLoading
    

    In the above PowerShell script which I ran from PowerShell ISE, I copy the demo database and LS component installers into the containers C:\run\my directory using the -myScripts parameter, and then replace the database used during installation using the -additionalParameters parameter.

    Note: you must match the correct Business Central image for your demo database. LS Central 13.04 is based on Business Central On-prem CU3, check the release notes for the version you need and adjust he image name in the script above.

    So far so good, we have a running container but if we try and use the system we’ll quickly bump into a missing component error. Next we’ll need to install the LS components.

    The NavContainerHelper Module has conveniently left a command line shortcut on my desktop:

    We can use this to install our LS components which we loaded into the container c:\Run\my directory earlier:

    We now have LS Central running in our Docker container.

    If you want to use the LS Windows Client POS you’ll also need to copy the LS client components into local RTC add-ins folder created by NavContainerHelper. Assuming the container name is LSDEMO, the local add-in folder can be found on the Docker host machine here:

    C:\ProgramData\NavContainerHelper\Extensions\LSDEMO\Program Files\130\RoleTailored Client\Add-ins

    Enjoy!

    See Part 2 to automate creation further:

    How-to: Run LS Central in a Docker container – Part 2

     

  • Add User in Dynamics NAV and Business Central On-premise with Powershell

    If you have access to an account with local administrator privileges to a Windows box hosting the Dynamics NAV or Business Central service, you can add your own user very easily with Powershell.

    Note: This post is about the on-premise version of Business Central (formerly Dynamics NAV), to add a user to Business Central Cloud/SaaS see here: Add User in Business Central Cloud / SaaS

    This functionality has been available for quite sometime in Dynamics NAV and continues to be applicable to Business Central On-premise… so it surprises me how often I get asked for a NAV user by technical staff. I’ll now be forwarding this blog post when asked!

    Another use for this of course (amongst other things) is when you need to restore a database which doesn’t contain a login you have access to. In the past we had to clear out the User related tables in SQL so NAV would give us access on first log on.

    There are two Cmdlets we need:

    New-NAVServerUser – Used to create the NAV user

    New-NAVServerUserPermissionSet – Used to assign a Permission Set to the user.

    As of Business Central CU03, the Cmdlets still have “NAV” in their name.

    So for example, using the Business Central or Dynamics NAV Administration Shell (run as administrator) we can add a new Windows user to NAV/BC and assign the SUPER Permission Set as follows:

    
    > New-NAVServerUser ServiceInstanceName -WindowsAccount DOMAIN\User.Name
    > New-NAVServerUserPermissionSet 
    ServiceInstanceName -WindowsAccount DOMAIN\User.Name -PermissionSetId SUPER

    If you want to add your currently logged on Windows user you can use the whoami command:

    
    > New-NAVServerUser ServiceInstanceName -WindowsAccount $(whoami)
    > New-NAVServerUserPermissionSet 
    ServiceInstanceName -WindowsAccount $(whoami) -PermissionSetId SUPER
  • Dynamics NAV Web Client – Server Error in Application

    When attempting to access the Dynamics NAV Web Client the following error is displayed in the browser:

    Dynamics NAV Web Client - Server Error in Application
    Dynamics NAV Web Client – Server Error in Application

    Server Error in '/' Application.
    
    Configuration Error
     Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
    
    Parser Error Message: It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.
    
    Source Error:
    
    Line 8:      <compilation debug="false" defaultLanguage="c#" targetFramework="4.0"/>
    Line 9:      <httpRuntime requestValidationMode="2.0" />
    Line 10:     <sessionState mode="InProc"/>
    Line 11:     <trust legacyCasModel="true" level="Full" />
    Line 12:     <!-- Uncomment to only allow https connection authentication mode
    
    Source File: C:\inetpub\wwwroot\sr-dev\webclient\web.config Line: 10

    As the parser error message states above “This error can be caused by a virtual directory not being configured as an application in IIS.”, we need to check that the Web Client directory in IIS has been set as an application. To do this:

    1. Open IIS Manager (hit the Windows key and type IIS) on the server hosting the Web Client components.
    2. Look for the Web Client directory, usually under Sites/Default Web Site.
    3. Expand to show the directory called WebClient, right click on this directory and select Convert to Application:

    Web Client Components - Convert to Application
    Web Client Components – Convert to Application

    After clicking Convert to Application a dialog box will pop up, click OK. You should notice the icon on the WebClient directory has changed.

    Try to open the Web Client again and hopefully the issue is fixed!

    Bonus points if anyone can tell me why it broke in the first place…

  • Update Dynamics NAV Licenses on Remote Hosts

    To update Dynamics NAV licenses of multiple databases used to be a bit of a headache. We have customers running independent NAV instances in the hundreds using LS Retail POS. Imagine having to log into each machine manually:

    1. Connect to the remote host.
    2. Upload the Dynamics NAV license file to the remote host.
    3. Import the license file.
    4. Restart the Dynamics NAV Service Tiers.

    Maybe you have multiple development / test machines which need a yearly license update?

    In this blog post I demonstrate how you can update NAV licenses on multiple remote hosts all from the comfort of your own PowerShell prompt. Hopefully, along the way you’ll pick up some PowerShell tricks to make your life easier!

    Update Dynamics NAV License Centrally on Multiple NAV Servers
    Update Dynamics NAV License Centrally on Multiple NAV Servers

    Before we get started there are a few prerequisites to this technique:

    • The remote hosts are on the same domain.
    • The user account running the PowerShell script has local admin on the host.

    Connecting to a remote host with PowerShell

    PowerShell comes with a utility called PowerShell Remoting. This allows us to connect to remote servers which have PowerShell Remoting enabled. Windows Server 2012 R2 and above have PowerShell Remoting enabled by default, but if we need to enable this manually we can run the following command on the host:

    > Enable-PSRemoting -force

    If the -force option is not used a prompt asking if we want to continue will occur.

    Group Policy can be used to centrally enable PowerShell Remoting.

    With Remoting enabled we can start a remote session using the Enter-PSSession cmdlet:

    > Enter-PSSession -ComputerName <hostname>

    Specifying a different set of credentials than the current Windows credentials can be done by adding the -Credential parameter:

    > Enter-PSSession -ComputerName <hostname> -Credential <domain\user.name>

    A password prompt will appear if we specify a user account.

    The Enter-PSSession cmdlet is handy when we want to enter into an interactive session with a remote host, but it will come up short when we want to start automating our scripts.

    New-PSSession is used to create a PowerShell session. This session can be a remote session and we can assign this session to a variable. This session variable can be used with the Invoke-Command cmdlet.

    For example, we could create a remote session and get a list of services on the remote host with:

    $session = New-PSSession -Computer <hostname>
    
    Invoke-Command -Session $session -ScriptBlock { Get-Service }

    In a scenario where we have a list of remote hosts to process, we will likely want to keep a note of any hosts that fail to respond. A simple method is to write any failures out to a text file. We can catch these failures in a try / catch block:

    $RemoteHosts = "Host1", "Host2", "Host3"
    
    foreach ($RemoteHost in $RemoteHosts) {
      try {
        $session = New-PSSession -Computer $RemoteHost
    
        Invoke-Command -Session $session -ScriptBlock { Get-Service }
      } catch {
        Add-Content -Path "C:\Temp\ErrorLog.txt" -Value ("Error creating remote session on: " + $RemoteHost)
      }
    }

    The Add-Content cmdlet will append values to the end of the file specified, creating the file if it doesn’t exist.

    Send the local NAV license file to the host machine

    I thought about a few options for getting the license file on the host machine:

    • Put the license file on a web server or fileshare and download from the host.
    • Copy the file through the Copy-Item Cmdlet using the -FromSession parameter.

    But the most convenient in this scenario is to put the license data in a byte array and pass it into the Import-NAVServerLicense Cmdlet using the -LicenseData parameter.

    To create a byte array from the NAV license file we can use the following code:

    > [byte[]]$LicenseData = Get-Content -Path "C:\Temp\License.flf" -Encoding Byte

    $LicenseData now contains the new NAV license, but we’ve created this variable in our local PowerShell session. Once we’ve created the remote session we will need to pass this variable in to the script block we are going to execute in the remote session. To do this, we can utilise script block parameters:

    [byte[]] $LicenseData = Get-Content -Path "C:\Temp\License.flf" -Encoding Byte
    
    $ScriptBlock = {
      Param($LicenseDataParam)
      # some code here...
    }
    
    $RemoteSession = New-PSSesssion -ComputerName <RemoteHost>
    
    Invoke-Command -Session $RemoteSession -ScriptBlock $ScriptBlock -ArgumentList (,$LicenseData)
    
    

    You may have noticed the -ArgumentList value looks a bit weird: (,$LicenseData). This is because the -ArgumentList parameter expects an array value, and will pass our byte array through as individual elements. That said, I’ve no idea why this syntax works… Stack Overflow to the rescue!

    If you don’t use the (,$ArrayVar) syntax, expect an error message like this:

    The license file is corrupt. Error Code: -200.
     + CategoryInfo : NotSpecified: (0:Int32) [Import-NAVServerLicense], FaultException`1
     + FullyQualifiedErrorId : MicrosoftDynamicsNavServer$DynamicsNAV110,Microsoft.Dynamics.Nav.Management.Cmdlets.ImportNavServerLicense
     + PSComputerName : REMOTEHOST

    Importing the license into Dynamics NAV

    So far we can create a remote session, move the license data to the remote host and execute script block on the remote host. Next we need to import the license into the remote Dynamics NAV instance. This is done using the Import-NAVServerLicense cmdlet:

    > Import-NAVServerLicense <NAV Service Instance> -LicenseData <License Data>

    The minimum parameters we need are the Dynamics NAV service instance name and the license data. We’ve already got the license data in the $LicenseData byte array, so lets look at getting a service to use.

    To make this simple, I’m going to apply the license to any running services on the host. I’ve blogged about getting running services previously, here’s some PowerShell to return the service names of any running NAV services:

    > Get-NAVServerInstance | Where-Object {$_.State -eq 'running'} | Select-Object -ExpandProperty "ServerInstance"

    The following script will get a list of running Dynamics NAV services, apply the license using the first service found and then restart all Dynamics NAV services:

    # Put license data in Byte array
    [Byte[]]$LicenseData = Get-Content -Path "C:\Temp\License.flf" -Encoding Byte
    
    # Get list of running NAV services
    $NAVServices = Get-NAVServerInstance | Where-Object {$_.State -eq 'running'} | Select-Object -ExpandProperty "ServerInstance"
    
    # If variable is an array get the first index
    If ($NAVServices -is [array]) {
     $NAVService = $NAVServices[0]
    } else {
     $NAVService = $NAVServices
    }
    
    # Check we have a NAV service before we try to import a license
    if (-Not [string]::IsNullOrEmpty($NAVService)) {
     Import-NAVServerLicense $NAVService -LicenseData $LicenseData
    }
    
    # Restart the service(s)
    Restart-Service -Name $NAVServices

    Putting it all together: Update Dynamics NAV Licenses on remote machines

    OK, we’ve run through all the parts. Lets put this all in to one script:

    # Array of host machines
    $RemoteHosts = "NAVSERV01", "NAVSERV02", "NAVSERV03"
    
    # Text file with list of host machines
    # $RemoteHosts = Get-Content -Path "C:\Temp\NAVHostsList.txt"
    
    [Byte[]]$LicenseData = Get-Content -Path "C:\Temp\License.flf" -Encoding Byte
    
    $ScriptBlock = {
     param ($LicenseData)
    
     Import-Module 'C:\Program Files\Microsoft Dynamics NAV\110\Service\NAVAdminTool.ps1'
    
     $NAVServices = Get-NAVServerInstance | Where-Object {$_.state -eq 'running'} | Select-Object -ExpandProperty "ServerInstance"
    
     # If variable is an array get the first index
     If ($NAVServices -is [array]) {
       $NAVService = $NAVServices[0]
     } else {
       $NAVService = $NAVServices
     }
    
    # Check we have a NAV service before we try to import a license
     if (-Not [string]::IsNullOrEmpty($NAVService)) {
       Import-NAVServerLicense $NAVService -LicenseData $LicenseData
    
      # Restart the service(s)
       Restart-Service -Name $NAVServices
     }
    }
    foreach ($RemoteHost in $RemoteHosts) {
     try {
       $session = New-PSSession -Computer $RemoteHost
    
       Invoke-Command -Session $session -ScriptBlock $ScriptBlock -ArgumentList (,$LicenseData)
    
     } catch {
       Add-Content -Path "C:\Temp\ErrorLog.txt" -Value ("Error updating license on: " + $RemoteHost)
     }
    }

    Whilst this does the job, there is plenty of room for improvement. Error handling is very lightweight for a start. Issues connecting to a remote host will be logged in the ErrorLog file, but if any errors occur in the remote session you’ll only be able to view them from the console output. Also, this script only allows for a single version of NAV and assumes all services on a remote host are connected to the same database.

    So, feel free to use and adapt this script.. but do so at your own risk.

  • Restart Dynamics NAV Services with Powershell

    In this blog post I explain how you can restart Dynamics NAV services with Powershell, while also exploring a few of the available Cmdlets for selecting services and properties.

    Restarting a NAV service

    Restart-Service is a standard Powershell Cmdlet that will stop and then start Windows services. If the service is already stopped, then it will simply start the service.

    Restarting the default NAV 2017 service can be done as follows:

    PS C:\Windows\System32>Restart-Service 'MicrosoftDynamicsNavServer$DynamicsNAV100'

    The unnamed parameter ‘MicrosoftDynamicsNavServer$DynamicsNAV100’ is the service name, this is always the Dynamics NAV Server instance name prefixed with MicrosoftDynamicsNavServer$.

    NAV Service Properties
    The properties of the default NAV 2017 service

    Restarting multiple NAV services

    Restarting multiple services can be done simply by using the * wildcard in the service name parameter:

    PS C:\Windows\System32>Restart-Service 'MicrosoftDynamicsNavServer*'

    The above command will restart every service with a name beginning with MicrosoftDynamicsNavServer.

    So far the services selected for restart have been very indiscriminate, we’ve simply restarted all NAV services on the machine… What if we need to be a bit more selective?

    Get-Service provides us with the ability to get objects representing Windows services. To get all services on your machine run Get-Service with no parameters:

    PS C:\Windows\System32>Get-Service

    The above command will print out a list of services and there statuses:

    Output of the Get-Service Cmdlet

    The same wildcard used for the Restart-Service Cmdlet can be used with Get-Service using the -Name parameter:

    PS C:\Windows\system32> Get-Service -Name 'MicrosoftDynamicsNavServer*'

    The benefit of using Get-Service however, is the ability to pipe the output to the Where-Object Cmdlet:

    PS C:\Windows\system32> Get-Service -Name 'MicrosoftDynamicsNavServer*' | Where-Object {$_.Status -eq "Running"}

    We now have a list of services starting with the name “MicrosoftDynamicsNavServer”, with a status of running:

    Restart Dynamics NAV Service with Powershell
    Get-Service running services

    To keep things consistent, lets delegate all the filtering to Where-Object:

    PS C:\Windows\system32> Get-Service | Where-Object {$_.Status -eq "Running" -and $_.Name -like 'MicrosoftDynamicsNavServer*'}

    Get running NAV services with Get-Service and Where-Object

    The output of Where-Object can be piped into Restart-Service.. so by piping Get-Service into Where-Object into Restart-Service, we can now restart all currently running NAV services with the following:

    PS C:\Windows\system32> Get-Service | Where-Object {$_.Status -eq "Running" -and $_.Name -like 'MicrosoftDynamicsNavServer*'} | Restart-Service

    Get-NAVServiceInstance

    As always, there are many ways to skin a cat.. We could also approach this problem from another direction. The Get-NavServerInstance Cmdlet is available in the NavAdminTool.ps1 script file found in the NAV service folder. The script file will need to be loaded into your Powershell environement using the Import-Module Cmdlet:

    PS C:\Windows\system32> Import-Module 'C:\Program Files\Microsoft Dynamics NAV\100\Service\NavAdminTool.ps1'

    If you get the following error:

    Execution policy error

    You can change the execution policy using the Execution-Policy Cmdlet. In the following image you can see that I get the current execution policy for reference and then after changing the execution policy, I am able to run the Import-Module Cmdlet:

    Powershell change execution policy

    For security reasons it’s good practice to change the execution policy back:

    PS C:\Windows\system32> Set-ExecutionPolicy -ExecutionPolicy Restricted

    Get-NavServerInstance returns a list of NAV services, but the output is not compatable with the Restart-Service Cmdlet:

    Output of Get-NavServerInstance

    We can however pipe the output into the Select-Object Cmdlet which we can use to get the service names as string objects:
    PS C:\Windows\system32> Get-NavServerInstance | Select-Object -ExpandProperty "ServerInstance"

    Get-NavServerInstance ServerInstance Property

    The string objects can then be piped directly into the Restart-Service Cmdlet:

    PS C:\Windows\system32> Get-NavServerInstance | Select-Object -Expand "ServerInstance" | Restart-Service

    Or we can pipe into Get-Service first, followed by Where-Object for more filtering options:

    PS C:\Windows\system32> Get-NavServerInstance | Select-Object -ExpandProperty "ServerInstance" | Get-Service | Where-Object {$_.Status -eq 'running'} | Restart-Service