Functions/PlatformManagement/Get-BcComponent.ps1
<#
.Synopsis Scans host system on installed NAV components, installation location and installation details .DESCRIPTION Scans host system on installed NAV components, installation location and installation details .PARAMETER BcVersion The Bc Version, example: 'bc21', 'nav2017', 'bc17', 'nav2013 R2' .EXAMPLE $NavComponents = Get-NavComponents -BcVersion "nav2017" .EXAMPLE $NavComponents = Get-NavComponents -BcVersion "nav2013 R2" #> function Get-BcComponent { [CmdletBinding()] [OutputType([array])] Param ( [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)] $BcVersion, $Computer = $env:COMPUTERNAME ) # Validate BC Version and get BC version folder $BcVersion = Get-BcVersion -BcVersion $BcVersion $scriptBlock = [scriptblock] { param ( $BcVersion ) # Helper functions function Get-NavComponentsFromWinReg { param( $NavComponents ) # Create an instance of the Registry Object and open the HKLM base key $Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',$($env:computername)) $Architectures = @("32", "64") foreach ($Architecture in $Architectures) { if ($Architecture -eq "32") { # Reg locations of currently Installed 32bit or 32/64bit programs $UninstallKey = "SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall" } if ($Architecture -eq "64") { # Reg locations of currently Installed 64bit programs $UninstallKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" } # Drill down into the Uninstall key for the corresponding architecture using the OpenSubKey Method $Regkey = $Reg.OpenSubKey($UninstallKey) Write-Verbose "Reg path for $Architecture bit: $UninstallKey" # Retrieve an array of string that contain all the subkey names from the Uninstall registery tree $subkeys = $Regkey.GetSubKeyNames() # Open each Subkey to check if it's a NAV component foreach ($key in $subkeys) { $thisKey = $UninstallKey + "\\" + $key # Open the subkey $thisSubKey = $Reg.OpenSubKey($thisKey) # If the regkey doesn't contain a NAV component: continue if (-not $thisSubKey.GetValue("DisplayName") -or $thisSubKey.GetValue("DisplayName") -notin $NavComponents.Displayname) { continue } # Match the regkey with the correct NAV components and add the information from the regkey to the nav component array foreach ($Component in $NavComponents) { if ($Component.Displayname -ne $thisSubKey.GetValue("DisplayName")) { continue } # If the display name matches, check if the major version of the product correspond. # Unlike NAV the Business Central releases do not have an unique identifiers in the displayname. if ($thisSubKey.GetValue("DisplayVersion") -notlike ('{0}*' -f $BcVersion.VersionFolder.Substring(0,2))) { continue } $Component.DisplayVersion = $($thisSubKey.GetValue("DisplayVersion")) $Component.InstallLocation = $($thisSubKey.GetValue("InstallLocation")) $Component.InstallSource = $($thisSubKey.GetValue("InstallSource")) $Component.RegKey = $thisKey $Component.Bit = $Architecture # Validate the found component path if ($Component.InstallLocation) { if (Test-Path -Path $Component.InstallLocation) { $Component.IsInstalled = $True Write-Verbose "" Write-Verbose "$($Component.Displayname) found" Write-Verbose "File location: $($Component.InstallLocation)" Write-Verbose "Register location: $($Component.RegKey)" continue } # End if } # End if Write-Verbose "" Write-Verbose "$($Component.Displayname) found" Write-Verbose "Register location: $($Component.RegKey)" } # End foreach component } # End foreach subkey } # End foreach architecture $Reg.Close() return $NavComponents } # End function Get-NavComponentsFromWinReg function Get-NavComponentPaths { param( $NavComponents, $BCVersion ) foreach ($Component in $NavComponents) { if ($Component.Component -eq "ADCS") { $RegPath = 'SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft Dynamics NAV\\{0}\\Automated Data Capture System' -f $BCVersion.VersionFolder } if ($Component.Component -eq "HelpServer") { $RegPath = 'SOFTWARE\\Microsoft\\Microsoft Dynamics NAV\\{0}\\DynamicsNAV{0}Help' -f $BCVersion.VersionFolder } if ($Component.Component -eq "NST") { $RegPath = 'SOFTWARE\\Microsoft\\Microsoft Dynamics NAV\\{0}\\Service' -f $BCVersion.VersionFolder } if ($Component.Component -eq "OUTLOOK") { $RegPath = 'SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft Dynamics NAV\\{0}\\OutlookAddin' -f $BCVersion.VersionFolder } if ($Component.Component -eq "RTC") { $RegPath = 'SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft Dynamics NAV\\{0}\\RoleTailored Client' -f $BCVersion.VersionFolder } if ($Component.Component -eq "WEB CLIENT") { $RegPath = 'SOFTWARE\\Microsoft\\Microsoft Dynamics NAV\\{0}\\Web Client' -f $BCVersion.VersionFolder } $ComponentPath = Get-NavComponentPath ($RegPath) if ($ComponentPath) { $Component.IsInstalled = $True $Component.InstallLocation = $ComponentPath } if($RegPath){ Clear-Variable RegPath } Clear-Variable ComponentPath } return $NavComponents } # End function GetNavComponentPaths function Get-NavComponentPath ($RegPath) { # Create an instance of the Registry Object and open the HKLM base key $Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',$($env:computername)) $RegKey = $Reg.OpenSubKey($RegPath) if ($RegKey) { if ($RegKey.GetValue("Path")) { if (Test-Path -Path ($RegKey.GetValue("Path"))) { $ComponentPath = $RegKey.GetValue("Path") return $ComponentPath } } } $ComponentPath = $False $Reg.Close() return $ComponentPath } # End function GetNavComponentPath # End Helper functions # Excluded: BPA, TestToolKit, UpgradeToolKit, WindowsPowerShellScripts $properties = @{ 'Component' = '' 'DisplayName' = '' 'IsInstalled' = $false 'InstallLocation' = '' 'DisplayVersion' = '' 'InstallSource' = '' 'Bit' = '' 'RegKey' = '' } $components = [ordered] @{ 'ADCS' = 'Microsoft Dynamics NAV Automated Data Capture System' 'HelpServer' = 'Microsoft Dynamics NAV {0} Help' -f $BcVersion.VersionNumber 'NST' = 'Microsoft Dynamics NAV {0} Server' -f $BcVersion.VersionNumber 'OUTLOOK' = 'Microsoft Dynamics NAV {0} Outlook Add-in' -f $BcVersion.VersionNumber 'RTC' = 'Microsoft Dynamics NAV {0} RoleTailored Client' -f $BcVersion.VersionNumber 'WEB CLIENT' = 'Microsoft Dynamics NAV {0} Web Client' -f $BcVersion.VersionNumber } if($BcVersion.ProductAbb -eq 'BC'){ $components = [ordered] @{ 'ADCS' = 'Microsoft Dynamics NAV Automated Data Capture System' 'HelpServer' = 'Microsoft Dynamics 365 Business Central Help' 'NST' = 'Microsoft Dynamics 365 Business Central Server' 'OUTLOOK' = 'Microsoft Dynamics 365 Business Central Outlook Add-in' 'RTC' = 'Microsoft Dynamics NAV RoleTailored Client' 'WEB CLIENT' = 'Microsoft Dynamics 365 Business Central Web Client' } } $NavComponents = @() foreach($key in $components.Keys){ $component = New-Object psobject -Property $properties $component.Component = $key $component.DisplayName = $components.$key $NavComponents += $component } $NavComponents = Get-NavComponentsFromWinReg -NavComponents $NavComponents -BcVersion $BcVersion $NavComponents = Get-NavComponentPaths -NavComponents $NavComponents -BcVersion $BcVersion return $NavComponents } # End Scriptblock # Do not add the computerName parameter if the host and target machine are the same. # This removes the requirement to have remote PowerShell enabled. $additionParams = @{} if ($Computer -ne 'localhost' -and $Computer -ne $env:COMPUTERNAME) { $additionParams = @{'ComputerName' = $Computer} } $result = Invoke-Command @additionParams -ScriptBlock $scriptBlock -ArgumentList $BcVersion return $result } Export-ModuleMember -Function Get-BcComponent |