From cf023184b97a4015c68f31410b73659899e5cea2 Mon Sep 17 00:00:00 2001 From: Florian Hopfner Date: Sat, 6 Jul 2024 15:28:30 +0200 Subject: [PATCH 1/8] add warnings for failing to update topology file --- .../functions/invoke-d365sdpinstall.ps1 | 55 ++++++++++--------- .../functions/update-topologyfile.ps1 | 6 ++ 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/d365fo.tools/functions/invoke-d365sdpinstall.ps1 b/d365fo.tools/functions/invoke-d365sdpinstall.ps1 index d9023b5a..c52c4e07 100644 --- a/d365fo.tools/functions/invoke-d365sdpinstall.ps1 +++ b/d365fo.tools/functions/invoke-d365sdpinstall.ps1 @@ -221,39 +221,41 @@ function Invoke-D365SDPInstall { #Update topology file (first command) $ok = Update-TopologyFile -Path $Path + if (-not $ok) { + Write-PSFMessage -Level Warning "Failed to update topology file." + return + } - if ($ok) { - $params = @( - "generate" - "-runbookId=`"$runbookId`"" - "-topologyFile=`"$topologyFile`"" - "-serviceModelFile=`"$serviceModelFile`"" - "-runbookFile=`"$runbookFile`"" - ) - - #Generate (second command) - Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath + $params = @( + "generate" + "-runbookId=`"$runbookId`"" + "-topologyFile=`"$topologyFile`"" + "-serviceModelFile=`"$serviceModelFile`"" + "-runbookFile=`"$runbookFile`"" + ) + + #Generate (second command) + Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath - if (Test-PSFFunctionInterrupt) { return } + if (Test-PSFFunctionInterrupt) { return } - $params = @( - "import" - "-runbookFile=`"$runbookFile`"" - ) + $params = @( + "import" + "-runbookFile=`"$runbookFile`"" + ) - Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath + Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath - if (Test-PSFFunctionInterrupt) { return } + if (Test-PSFFunctionInterrupt) { return } - $params = @( - "execute" - "-runbookId=`"$runbookId`"" - ) + $params = @( + "execute" + "-runbookId=`"$runbookId`"" + ) - Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath + Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath - if (Test-PSFFunctionInterrupt) { return } - } + if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose "All manual steps complete." } @@ -264,6 +266,9 @@ function Invoke-D365SDPInstall { Write-PSFMessage -Level Verbose "Updating topology file xml." $ok = Update-TopologyFile -Path $Path + if (-not $ok) { + Write-PSFMessage -Level Warning "Failed to update topology file." + } $RunCommand = $false } 'generate' { diff --git a/d365fo.tools/internal/functions/update-topologyfile.ps1 b/d365fo.tools/internal/functions/update-topologyfile.ps1 index c7a498d0..0218e028 100644 --- a/d365fo.tools/internal/functions/update-topologyfile.ps1 +++ b/d365fo.tools/internal/functions/update-topologyfile.ps1 @@ -50,6 +50,12 @@ function Update-TopologyFile { $models = [Microsoft.Dynamics.AX.AXInstallationInfo.AXInstallationInfo]::GetInstalledServiceModel() + if ($null -eq $models -or $models.Count -eq 0) { + Write-PSFMessage -Level Warning "No installed service models found." + Write-PSFMessage -Level Output "On a local VHD environment, this can be caused by an empty C:\Logs\InstallationRecords\ServiceModelInstallationRecords folder." + return $false + } + foreach ($name in $models.Name) { $element = $xml.CreateElement('string') $element.InnerText = $name From cbf8c182494f94256a9d56979dc68bdafa5b3c82 Mon Sep 17 00:00:00 2001 From: Florian Hopfner Date: Sat, 6 Jul 2024 15:44:20 +0200 Subject: [PATCH 2/8] add fallback list of service models fixes #843 --- .../functions/update-topologyfile.ps1 | 10 ++++++++-- d365fo.tools/internal/scripts/variables.ps1 | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/d365fo.tools/internal/functions/update-topologyfile.ps1 b/d365fo.tools/internal/functions/update-topologyfile.ps1 index 0218e028..82d22fb9 100644 --- a/d365fo.tools/internal/functions/update-topologyfile.ps1 +++ b/d365fo.tools/internal/functions/update-topologyfile.ps1 @@ -52,8 +52,14 @@ function Update-TopologyFile { if ($null -eq $models -or $models.Count -eq 0) { Write-PSFMessage -Level Warning "No installed service models found." - Write-PSFMessage -Level Output "On a local VHD environment, this can be caused by an empty C:\Logs\InstallationRecords\ServiceModelInstallationRecords folder." - return $false + Write-PSFMessage -Level Output "Using fallback list of known service model names." + $serviceModelNames = $Script:FallbackInstallationServiceModelNames + $models = $serviceModelNames | ForEach-Object { + [PSCustomObject]@{ + Name = $_ + } + } + } foreach ($name in $models.Name) { diff --git a/d365fo.tools/internal/scripts/variables.ps1 b/d365fo.tools/internal/scripts/variables.ps1 index 0c2637d5..4bcd088f 100644 --- a/d365fo.tools/internal/scripts/variables.ps1 +++ b/d365fo.tools/internal/scripts/variables.ps1 @@ -94,6 +94,25 @@ $RegSplat = @{ $RegValue = $( if (Test-RegistryValue @RegSplat) { Join-Path (Get-ItemPropertyValue @RegSplat) "InstallationRecords" } else { "" } ) $Script:InstallationRecordsDir = $RegValue +# On a local VHD, the information about the installed service models may not be available. +# As a fallback, this list of known service model names may be used. +$Script:FallbackInstallationServiceModelNames = @( + "ALMService", + "AOSService", + "BIService", + "DevToolsService", + "DIXFService", + "MROneBox", + "PayrollTaxModule", + "PerfSDK", + "ReportingService", + "RetailCloudPos", + "RetailHQConfiguration", + "RetailSDK", + "RetailSelfService", + "RetailServer" +) + $Script:UserIsAdmin = $env:UserName -like "*admin*" $Script:TfDir = "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\" From 74a8acc19e2363638ae8e758797f95cbbb79e856 Mon Sep 17 00:00:00 2001 From: Florian Hopfner Date: Sat, 6 Jul 2024 16:30:13 +0200 Subject: [PATCH 3/8] update topology file other than DefaultTopologyData.xml --- .../functions/update-topologyfile.ps1 | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/d365fo.tools/internal/functions/update-topologyfile.ps1 b/d365fo.tools/internal/functions/update-topologyfile.ps1 index 82d22fb9..2ab88f99 100644 --- a/d365fo.tools/internal/functions/update-topologyfile.ps1 +++ b/d365fo.tools/internal/functions/update-topologyfile.ps1 @@ -1,4 +1,4 @@ - + <# .SYNOPSIS Update the topology file @@ -7,12 +7,17 @@ Update the topology file based on the already installed list of services on the machine .PARAMETER Path - Path to the folder where the topology XML file that you want to work against is placed + Path to the folder where the Microsoft.Dynamics.AX.AXInstallationInfo.dll assembly is located Should only contain a path to a folder, not a file + + .PARAMETER TopologyFile + Path to the topology file to update + + If not specified, the default topology file will be used .EXAMPLE - PS C:\> Update-TopologyFile -Path "c:\temp\d365fo.tools\DefaultTopologyData.xml" + PS C:\> Update-TopologyFile -Path "c:\temp\UpdatePackageFolder" -TopologyFile "c:\temp\d365fo.tools\DefaultTopologyData.xml" This will update the "c:\temp\d365fo.tools\DefaultTopologyData.xml" file with all the installed services on the machine. @@ -29,12 +34,16 @@ function Update-TopologyFile { [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] - [string]$Path + [string]$Path, + + [string]$TopologyFile ) - $topologyFile = Join-Path $Path 'DefaultTopologyData.xml' + if (-not $TopologyFile) { + $topologyFile = Join-Path $Path 'DefaultTopologyData.xml' + } - Write-PSFMessage -Level Verbose "Creating topology file: $topologyFile" + Write-PSFMessage -Level Verbose "Updating topology file: $topologyFile" [xml]$xml = Get-Content $topologyFile $machine = $xml.TopologyData.MachineList.Machine From fd4c0635c0a42297c338f036f057633ce70285c2 Mon Sep 17 00:00:00 2001 From: Florian Hopfner Date: Sat, 6 Jul 2024 16:30:31 +0200 Subject: [PATCH 4/8] handle empty ServiceModelList node --- d365fo.tools/internal/functions/update-topologyfile.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/d365fo.tools/internal/functions/update-topologyfile.ps1 b/d365fo.tools/internal/functions/update-topologyfile.ps1 index 2ab88f99..2611bc6d 100644 --- a/d365fo.tools/internal/functions/update-topologyfile.ps1 +++ b/d365fo.tools/internal/functions/update-topologyfile.ps1 @@ -1,4 +1,4 @@ - + <# .SYNOPSIS Update the topology file @@ -49,7 +49,7 @@ function Update-TopologyFile { $machine = $xml.TopologyData.MachineList.Machine $machine.Name = $env:computername - $serviceModelList = $machine.ServiceModelList + $serviceModelList = $xml.SelectSingleNode("//ServiceModelList") $null = $serviceModelList.RemoveAll() [System.Collections.ArrayList] $Files2Process = New-Object -TypeName "System.Collections.ArrayList" From 232abe2bead3e08ab9d0f8fdf1dcda95b32ec0d5 Mon Sep 17 00:00:00 2001 From: Florian Hopfner Date: Sat, 6 Jul 2024 16:31:09 +0200 Subject: [PATCH 5/8] allow skipping of topology file update --- .../functions/invoke-d365sdpinstall.ps1 | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/d365fo.tools/functions/invoke-d365sdpinstall.ps1 b/d365fo.tools/functions/invoke-d365sdpinstall.ps1 index c52c4e07..0f0dd487 100644 --- a/d365fo.tools/functions/invoke-d365sdpinstall.ps1 +++ b/d365fo.tools/functions/invoke-d365sdpinstall.ps1 @@ -138,7 +138,11 @@ function Invoke-D365SDPInstall { [switch] $ShowOriginalProgress, - [switch] $OutputCommandOnly + [switch] $OutputCommandOnly, + + [string] $TopologyFile = "DefaultTopologyData.xml", + + [switch] $UseExistingTopologyFile ) if ((Get-Process -Name "devenv" -ErrorAction SilentlyContinue).Count -gt 0) { @@ -189,10 +193,12 @@ function Invoke-D365SDPInstall { $Path = $absolutePath } - # $Util = Join-Path $Path "AXUpdateInstaller.exe" $executable = Join-Path $Path "AXUpdateInstaller.exe" - $topologyFile = Join-Path $Path 'DefaultTopologyData.xml' + + if (-not ([System.IO.Path]::IsPathRooted($TopologyFile) -or (Split-Path -Path $TopologyFile -IsAbsolute))) { + $TopologyFile = Join-Path -Path $Path -ChildPath $TopologyFile + } if (-not (Test-PathExists -Path $topologyFile, $executable -Type Leaf)) { return } @@ -214,16 +220,17 @@ function Invoke-D365SDPInstall { $Command = $Command.ToLowerInvariant() $runbookFile = Join-Path $Path "$runbookId.xml" $serviceModelFile = Join-Path $Path 'DefaultServiceModelData.xml' - $topologyFile = Join-Path $Path 'DefaultTopologyData.xml' if ($Command -eq 'runall') { Write-PSFMessage -Level Verbose "Running all manual steps in one single operation" #Update topology file (first command) - $ok = Update-TopologyFile -Path $Path - if (-not $ok) { - Write-PSFMessage -Level Warning "Failed to update topology file." - return + if (-not $UseExistingTopologyFile) { + $ok = Update-TopologyFile -Path $Path -TopologyFile $TopologyFile + if (-not $ok) { + Write-PSFMessage -Level Warning "Failed to update topology file." + return + } } $params = @( @@ -265,7 +272,11 @@ function Invoke-D365SDPInstall { 'settopology' { Write-PSFMessage -Level Verbose "Updating topology file xml." - $ok = Update-TopologyFile -Path $Path + if ($UseExistingTopologyFile) { + Write-PSFMessage -Level Warning "The SetTopology command is used to update a topology file. The UseExistingTopologyFile switch should not be used with this command." + return + } + $ok = Update-TopologyFile -Path $Path -TopologyFile $TopologyFile if (-not $ok) { Write-PSFMessage -Level Warning "Failed to update topology file." } From 2f54dd0bf06a49b5ee5aebf686e551508c71475c Mon Sep 17 00:00:00 2001 From: Florian Hopfner Date: Sat, 6 Jul 2024 16:54:52 +0200 Subject: [PATCH 6/8] add documentation for new parameters --- .../functions/invoke-d365sdpinstall.ps1 | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/d365fo.tools/functions/invoke-d365sdpinstall.ps1 b/d365fo.tools/functions/invoke-d365sdpinstall.ps1 index 0f0dd487..522ddf32 100644 --- a/d365fo.tools/functions/invoke-d365sdpinstall.ps1 +++ b/d365fo.tools/functions/invoke-d365sdpinstall.ps1 @@ -62,6 +62,12 @@ Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection + + .PARAMETER TopologyFile + Provide a custom topology file to use. By default, the cmdlet will use the DefaultTopologyData.xml file in the package directory. + + .PARAMETER UseExistingTopologyFile + Use this switch to indicate that the topology file is already updated and should not be updated again. .EXAMPLE PS C:\> Invoke-D365SDPInstall -Path "c:\temp\package.zip" -QuickInstallAll @@ -97,7 +103,16 @@ PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -Command SetStepComplete -Step 24 -RunbookId 'MyRunbook' Mark step 24 complete in runbook with id 'MyRunbook' and continue the runbook from the next step. - + + .EXAMPLE + PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -Command SetTopology -TopologyFile "c:\temp\MyTopology.xml" + + Update the MyTopology.xml file with all the installed services on the machine. + + .EXAMPLE + PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -Command RunAll -TopologyFile "c:\temp\MyTopology.xml" -UseExistingTopologyFile + + Run all manual steps in one single operation using the MyTopology.xml file. The topology file is not updated. .NOTES Author: Tommy Skaue (@skaue) From db9de2c924598fd9f9fae1b51ac2408bc6ca42bc Mon Sep 17 00:00:00 2001 From: Florian Hopfner Date: Sat, 6 Jul 2024 17:01:58 +0200 Subject: [PATCH 7/8] remove trailing white space --- d365fo.tools/functions/invoke-d365sdpinstall.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/d365fo.tools/functions/invoke-d365sdpinstall.ps1 b/d365fo.tools/functions/invoke-d365sdpinstall.ps1 index 522ddf32..2da33f55 100644 --- a/d365fo.tools/functions/invoke-d365sdpinstall.ps1 +++ b/d365fo.tools/functions/invoke-d365sdpinstall.ps1 @@ -254,7 +254,7 @@ function Invoke-D365SDPInstall { "-topologyFile=`"$topologyFile`"" "-serviceModelFile=`"$serviceModelFile`"" "-runbookFile=`"$runbookFile`"" - ) + ) #Generate (second command) Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath From a027b02a011519adcc52cafec7eb08800d1d4556 Mon Sep 17 00:00:00 2001 From: FH-Inway Date: Sat, 6 Jul 2024 15:03:21 +0000 Subject: [PATCH 8/8] =?UTF-8?q?=F0=9F=A4=96=20Fix=20best=20practice=20devi?= =?UTF-8?q?ations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This pull request was automatically created by the d365fo.tools-Generate-Text action' --- d365fo.tools/bin/d365fo.tools-index.json | 20 ++++++- .../functions/invoke-d365sdpinstall.ps1 | 12 ++-- .../functions/update-topologyfile.ps1 | 2 +- .../functions/Invoke-D365SDPInstall.Tests.ps1 | 32 ++++++++++- docs/Invoke-D365SDPInstall.md | 55 ++++++++++++++++++- 5 files changed, 106 insertions(+), 15 deletions(-) diff --git a/d365fo.tools/bin/d365fo.tools-index.json b/d365fo.tools/bin/d365fo.tools-index.json index 1eb591a2..2275e5f5 100644 --- a/d365fo.tools/bin/d365fo.tools-index.json +++ b/d365fo.tools/bin/d365fo.tools-index.json @@ -9053,6 +9053,22 @@ false, "false", "False" + ], + [ + "TopologyFile", + "Provide a custom topology file to use. By default, the cmdlet will use the DefaultTopologyData.xml file in the package directory.", + "", + false, + "false", + "DefaultTopologyData.xml" + ], + [ + "UseExistingTopologyFile", + "Use this switch to indicate that the topology file is already updated and should not be updated again.", + "", + false, + "false", + "False" ] ], "Alias": "", @@ -9060,8 +9076,8 @@ "Synopsis": "Invoke the AxUpdateInstaller.exe file from Software Deployable Package (SDP)", "Name": "Invoke-D365SDPInstall", "Links": null, - "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\package.zip\" -QuickInstallAll\nThis will install the package contained in the c:\\temp\\package.zip file using a runbook in memory while executing.\n-------------------------- EXAMPLE 2 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -DevInstall\nThis will install the extracted package in c:\\temp\\ using a runbook in memory while executing.\nThis command is to be used on Microsoft Hosted Tier1 development environment, where you don\u0027t have access to the administrator user account on the vm.\n-------------------------- EXAMPLE 3 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command SetTopology\nPS C:\\\u003e Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command Generate -RunbookId \u0027MyRunbook\u0027\r\nPS C:\\\u003e Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command Import -RunbookId \u0027MyRunbook\u0027\r\nPS C:\\\u003e Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command Execute -RunbookId \u0027MyRunbook\u0027\nManual operations that first create Topology XML from current environment, then generate runbook with id \u0027MyRunbook\u0027, then import it and finally execute it.\n-------------------------- EXAMPLE 4 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RunAll\nCreate Topology XML from current environment. Using default runbook id \u0027Runbook\u0027 and run all the operations from generate, to import to execute.\n-------------------------- EXAMPLE 5 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RerunStep -Step 18 -RunbookId \u0027MyRunbook\u0027\nRerun runbook with id \u0027MyRunbook\u0027 from step 18.\n-------------------------- EXAMPLE 6 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command SetStepComplete -Step 24 -RunbookId \u0027MyRunbook\u0027\nMark step 24 complete in runbook with id \u0027MyRunbook\u0027 and continue the runbook from the next step.", - "Syntax": "Invoke-D365SDPInstall [-Path] \u003cString\u003e [[-MetaDataDir] \u003cString\u003e] [[-QuickInstallAll]] [[-Step] \u003cInt32\u003e] [[-RunbookId] \u003cString\u003e] [-LogPath \u003cString\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\u003cCommonParameters\u003e]\nInvoke-D365SDPInstall [-Path] \u003cString\u003e [[-MetaDataDir] \u003cString\u003e] [[-DevInstall]] [[-Step] \u003cInt32\u003e] [[-RunbookId] \u003cString\u003e] [-LogPath \u003cString\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\u003cCommonParameters\u003e]\nInvoke-D365SDPInstall [-Path] \u003cString\u003e [[-MetaDataDir] \u003cString\u003e] [-Command] \u003cString\u003e [[-Step] \u003cInt32\u003e] [[-RunbookId] \u003cString\u003e] [-LogPath \u003cString\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\u003cCommonParameters\u003e]" + "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\package.zip\" -QuickInstallAll\nThis will install the package contained in the c:\\temp\\package.zip file using a runbook in memory while executing.\n-------------------------- EXAMPLE 2 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -DevInstall\nThis will install the extracted package in c:\\temp\\ using a runbook in memory while executing.\nThis command is to be used on Microsoft Hosted Tier1 development environment, where you don\u0027t have access to the administrator user account on the vm.\n-------------------------- EXAMPLE 3 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command SetTopology\nPS C:\\\u003e Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command Generate -RunbookId \u0027MyRunbook\u0027\r\nPS C:\\\u003e Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command Import -RunbookId \u0027MyRunbook\u0027\r\nPS C:\\\u003e Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command Execute -RunbookId \u0027MyRunbook\u0027\nManual operations that first create Topology XML from current environment, then generate runbook with id \u0027MyRunbook\u0027, then import it and finally execute it.\n-------------------------- EXAMPLE 4 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RunAll\nCreate Topology XML from current environment. Using default runbook id \u0027Runbook\u0027 and run all the operations from generate, to import to execute.\n-------------------------- EXAMPLE 5 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RerunStep -Step 18 -RunbookId \u0027MyRunbook\u0027\nRerun runbook with id \u0027MyRunbook\u0027 from step 18.\n-------------------------- EXAMPLE 6 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command SetStepComplete -Step 24 -RunbookId \u0027MyRunbook\u0027\nMark step 24 complete in runbook with id \u0027MyRunbook\u0027 and continue the runbook from the next step.\n-------------------------- EXAMPLE 7 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command SetTopology -TopologyFile \"c:\\temp\\MyTopology.xml\"\nUpdate the MyTopology.xml file with all the installed services on the machine.\n-------------------------- EXAMPLE 8 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RunAll -TopologyFile \"c:\\temp\\MyTopology.xml\" -UseExistingTopologyFile\nRun all manual steps in one single operation using the MyTopology.xml file. The topology file is not updated.", + "Syntax": "Invoke-D365SDPInstall [-Path] \u003cString\u003e [[-MetaDataDir] \u003cString\u003e] [[-QuickInstallAll]] [[-Step] \u003cInt32\u003e] [[-RunbookId] \u003cString\u003e] [-LogPath \u003cString\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [-TopologyFile \u003cString\u003e] [-UseExistingTopologyFile] [\u003cCommonParameters\u003e]\nInvoke-D365SDPInstall [-Path] \u003cString\u003e [[-MetaDataDir] \u003cString\u003e] [[-DevInstall]] [[-Step] \u003cInt32\u003e] [[-RunbookId] \u003cString\u003e] [-LogPath \u003cString\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [-TopologyFile \u003cString\u003e] [-UseExistingTopologyFile] [\u003cCommonParameters\u003e]\nInvoke-D365SDPInstall [-Path] \u003cString\u003e [[-MetaDataDir] \u003cString\u003e] [-Command] \u003cString\u003e [[-Step] \u003cInt32\u003e] [[-RunbookId] \u003cString\u003e] [-LogPath \u003cString\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [-TopologyFile \u003cString\u003e] [-UseExistingTopologyFile] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365SeleniumDownload", diff --git a/d365fo.tools/functions/invoke-d365sdpinstall.ps1 b/d365fo.tools/functions/invoke-d365sdpinstall.ps1 index 2da33f55..9b3f28d1 100644 --- a/d365fo.tools/functions/invoke-d365sdpinstall.ps1 +++ b/d365fo.tools/functions/invoke-d365sdpinstall.ps1 @@ -62,10 +62,10 @@ Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection - + .PARAMETER TopologyFile Provide a custom topology file to use. By default, the cmdlet will use the DefaultTopologyData.xml file in the package directory. - + .PARAMETER UseExistingTopologyFile Use this switch to indicate that the topology file is already updated and should not be updated again. @@ -103,15 +103,15 @@ PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -Command SetStepComplete -Step 24 -RunbookId 'MyRunbook' Mark step 24 complete in runbook with id 'MyRunbook' and continue the runbook from the next step. - + .EXAMPLE PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -Command SetTopology -TopologyFile "c:\temp\MyTopology.xml" - + Update the MyTopology.xml file with all the installed services on the machine. - + .EXAMPLE PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -Command RunAll -TopologyFile "c:\temp\MyTopology.xml" -UseExistingTopologyFile - + Run all manual steps in one single operation using the MyTopology.xml file. The topology file is not updated. .NOTES diff --git a/d365fo.tools/internal/functions/update-topologyfile.ps1 b/d365fo.tools/internal/functions/update-topologyfile.ps1 index 2611bc6d..e712b918 100644 --- a/d365fo.tools/internal/functions/update-topologyfile.ps1 +++ b/d365fo.tools/internal/functions/update-topologyfile.ps1 @@ -10,7 +10,7 @@ Path to the folder where the Microsoft.Dynamics.AX.AXInstallationInfo.dll assembly is located Should only contain a path to a folder, not a file - + .PARAMETER TopologyFile Path to the topology file to update diff --git a/d365fo.tools/tests/functions/Invoke-D365SDPInstall.Tests.ps1 b/d365fo.tools/tests/functions/Invoke-D365SDPInstall.Tests.ps1 index 606348d5..d36341f9 100644 --- a/d365fo.tools/tests/functions/Invoke-D365SDPInstall.Tests.ps1 +++ b/d365fo.tools/tests/functions/Invoke-D365SDPInstall.Tests.ps1 @@ -141,24 +141,50 @@ $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } + It 'Should have the expected parameter TopologyFile' { + $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['TopologyFile'] + $parameter.Name | Should -Be 'TopologyFile' + $parameter.ParameterType.ToString() | Should -Be System.String + $parameter.IsDynamic | Should -Be $False + $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' + $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' + $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 + $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False + } + It 'Should have the expected parameter UseExistingTopologyFile' { + $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['UseExistingTopologyFile'] + $parameter.Name | Should -Be 'UseExistingTopologyFile' + $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter + $parameter.IsDynamic | Should -Be $False + $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' + $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' + $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 + $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False + } } Describe "Testing parameterset QuickInstall" { <# QuickInstall -Path - QuickInstall -Path -MetaDataDir -QuickInstallAll -Step -RunbookId -LogPath -ShowOriginalProgress -OutputCommandOnly + QuickInstall -Path -MetaDataDir -QuickInstallAll -Step -RunbookId -LogPath -ShowOriginalProgress -OutputCommandOnly -TopologyFile -UseExistingTopologyFile #> } Describe "Testing parameterset DevInstall" { <# DevInstall -Path - DevInstall -Path -MetaDataDir -DevInstall -Step -RunbookId -LogPath -ShowOriginalProgress -OutputCommandOnly + DevInstall -Path -MetaDataDir -DevInstall -Step -RunbookId -LogPath -ShowOriginalProgress -OutputCommandOnly -TopologyFile -UseExistingTopologyFile #> } Describe "Testing parameterset Manual" { <# Manual -Path -Command - Manual -Path -MetaDataDir -Command -Step -RunbookId -LogPath -ShowOriginalProgress -OutputCommandOnly + Manual -Path -MetaDataDir -Command -Step -RunbookId -LogPath -ShowOriginalProgress -OutputCommandOnly -TopologyFile -UseExistingTopologyFile #> } diff --git a/docs/Invoke-D365SDPInstall.md b/docs/Invoke-D365SDPInstall.md index cbd19df8..d7f14ebc 100644 --- a/docs/Invoke-D365SDPInstall.md +++ b/docs/Invoke-D365SDPInstall.md @@ -15,19 +15,22 @@ Invoke the AxUpdateInstaller.exe file from Software Deployable Package (SDP) ### QuickInstall (Default) ``` Invoke-D365SDPInstall [-Path] [[-MetaDataDir] ] [-QuickInstallAll] [[-Step] ] - [[-RunbookId] ] [-LogPath ] [-ShowOriginalProgress] [-OutputCommandOnly] [] + [[-RunbookId] ] [-LogPath ] [-ShowOriginalProgress] [-OutputCommandOnly] + [-TopologyFile ] [-UseExistingTopologyFile] [] ``` ### DevInstall ``` Invoke-D365SDPInstall [-Path] [[-MetaDataDir] ] [-DevInstall] [[-Step] ] - [[-RunbookId] ] [-LogPath ] [-ShowOriginalProgress] [-OutputCommandOnly] [] + [[-RunbookId] ] [-LogPath ] [-ShowOriginalProgress] [-OutputCommandOnly] + [-TopologyFile ] [-UseExistingTopologyFile] [] ``` ### Manual ``` Invoke-D365SDPInstall [-Path] [[-MetaDataDir] ] [-Command] [[-Step] ] - [[-RunbookId] ] [-LogPath ] [-ShowOriginalProgress] [-OutputCommandOnly] [] + [[-RunbookId] ] [-LogPath ] [-ShowOriginalProgress] [-OutputCommandOnly] + [-TopologyFile ] [-UseExistingTopologyFile] [] ``` ## DESCRIPTION @@ -86,6 +89,21 @@ Invoke-D365SDPInstall -Path "c:\temp\" -Command SetStepComplete -Step 24 -Runboo Mark step 24 complete in runbook with id 'MyRunbook' and continue the runbook from the next step. +### EXAMPLE 7 +``` +Invoke-D365SDPInstall -Path "c:\temp\" -Command SetTopology -TopologyFile "c:\temp\MyTopology.xml" +``` + +Update the MyTopology.xml file with all the installed services on the machine. + +### EXAMPLE 8 +``` +Invoke-D365SDPInstall -Path "c:\temp\" -Command RunAll -TopologyFile "c:\temp\MyTopology.xml" -UseExistingTopologyFile +``` + +Run all manual steps in one single operation using the MyTopology.xml file. +The topology file is not updated. + ## PARAMETERS ### -Path @@ -264,6 +282,37 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -TopologyFile +Provide a custom topology file to use. +By default, the cmdlet will use the DefaultTopologyData.xml file in the package directory. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: DefaultTopologyData.xml +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -UseExistingTopologyFile +Use this switch to indicate that the topology file is already updated and should not be updated again. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).