Skip to content

Commit

Permalink
Feature: Add Get-D365SDPDetails
Browse files Browse the repository at this point in the history
Cmdlet can help with extracting the details about a package. Like what version was it build on. What modules are part of the package.
  • Loading branch information
Splaxi committed Nov 10, 2023
1 parent 7aabd53 commit 05a367c
Show file tree
Hide file tree
Showing 8 changed files with 374 additions and 6 deletions.
43 changes: 40 additions & 3 deletions d365fo.tools/bin/d365fo.tools-index.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions d365fo.tools/d365fo.tools.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@
'Get-D365RunbookLogFile',

'Get-D365SDPCleanUp',
'Get-D365SDPDetails',

'Get-D365Table',
'Get-D365TableField',
Expand Down
167 changes: 167 additions & 0 deletions d365fo.tools/functions/get-d365sdpdetails.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@

<#
.SYNOPSIS
Get details from the Software Deployable Package
.DESCRIPTION
Details details about the inner modules / packages that a Software Deployable Contains
.PARAMETER Path
Path to the Software Deployable Package that you want to work against
The cmdlet supports a path to a zip-file or directory with the unpacked content
.EXAMPLE
PS C:\> Get-D365SDPDetails -Path 'C:\Temp\RV-10.0.36.44.zip'
This will display the basic details about the package.
The package is a zip file.
A result set example:
Platform PlatformVersion Modules
-------- --------------- -------
Update55 7.0.6651.92 {@{Name=RapidValue; Version=7.0.6651.92}, @{Name=TCLCommon; Version=7.0.6651.92}, @{Name=TC...
.EXAMPLE
PS C:\> Get-D365SDPDetails -Path 'C:\Temp\RV-10.0.36.44'
This will display the basic details about the package.
The package is extracted to a local folder.
A result set example:
Platform PlatformVersion Modules
-------- --------------- -------
Update55 7.0.6651.92 {@{Name=RapidValue; Version=7.0.6651.92}, @{Name=TCLCommon; Version=7.0.6651.92}, @{Name=TC...
.EXAMPLE
PS C:\> Get-D365SDPDetails -Path 'C:\Temp\RV-10.0.36.44.zip' | Select-Object -ExpandProperty Modules
This will display the module details that are part of the package.
The package is a zip file.
A result set example:
Name Version
---- -------
RapidValue 7.0.6651.92
TCLCommon 7.0.6651.92
TCLLabel 7.0.6651.92
.NOTES
Author: Mötz Jensen (@Splaxi)
#>#
function Get-D365SDPDetails {
[CmdletBinding()]
param (
[Parameter(Mandatory = $True)]
[Alias('File')]
[string] $Path
)

$pathWorkDirectory = "$([System.IO.Path]::GetTempPath())d365fo.tools\$([System.Guid]::NewGuid().Guid)"
#Make sure the work path is created and available
New-Item -Path $pathWorkDirectory -ItemType Directory -Force -ErrorAction Ignore > $null
$pathHotfix = Join-Path -Path $pathWorkDirectory -ChildPath "HotfixInstallationInfo.xml"

Invoke-TimeSignal -Start

if ($Path.EndsWith(".zip")) {
<#
If we have a zip file, we'll extract the files, to mimic a folder
Will copy to the default Windows temporary folder
#>

Unblock-File -Path $Path

$file = [System.IO.File]::Open($Path, [System.IO.FileMode]::Open)
$zipArch = [System.IO.Compression.ZipArchive]::new($file)
$zipEntry = $zipArch.GetEntry("HotfixInstallationInfo.xml")

if (-not $zipEntry) {
$messageString = "Unable to find the <c='em'>HotfixInstallationInfo.xml</c> file inside the archive. It would indicate the <c='em'>$Path</c> isn't a valid software deployable package."
Write-PSFMessage -Level Host -Message $messageString
Stop-PSFFunction -Message "Stopping because HotfixInstallationInfo.xml wasn't found." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', '')))
}

if (Test-PSFFunctionInterrupt) { return }

[System.IO.Compression.ZipFileExtensions]::ExtractToFile($zipEntry, $pathHotfix, $true)


foreach ($nuget in $($zipArch.Entries | Where-Object Fullname -like "AOSService\Packages\*.nupkg")) {
$pathNuget = "$pathWorkDirectory\$($nuget.name).zip"

# The nuget file contains module name in correct casing
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($nuget, $pathNuget, $true)

}

# Clear out any zip archive objects from memory
if ($zipArch) {
$zipArch.Dispose()
}

if ($file) {
$file.Close()
$file.Dispose()
}
}
else {
<#
Will copy to the default Windows temporary folder
#>
Copy-Item -Path "$Path\HotfixInstallationInfo.xml" -Destination $pathHotfix -Force

foreach ($nuget in $(Get-ChildItem -Path "$Path\AOSService\Packages\*.nupkg")) {
Copy-Item -Path $nuget.FullName -Destination "$pathWorkDirectory\$($nuget.Name).zip" -Force
}
}

if (Test-PSFFunctionInterrupt) { return }

[System.Collections.Generic.List[System.Object]] $modules = @()

foreach ($nuget in $(Get-ChildItem -Path "$pathWorkDirectory\*.nupkg.zip")) {
<#
nuget contains a nuspec file
nuspec is a XML containing the details we are looking for
#>
$pathXml = $nuget.FullName + ".nuspec"

$fileNuget = [System.IO.File]::Open($nuget.FullName, [System.IO.FileMode]::Open)
$zipNuget = [System.IO.Compression.ZipArchive]::new($fileNuget)
$zipNugetEntry = $zipNuget.Entries | Where-Object Name -like "*.nuspec" | Select-Object -First 1
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($zipNugetEntry, $pathXml, $true)

[xml] $moduleSpec = Get-Content -Path $pathXml -Raw

$modules.Add(
[PSCustomObject]@{
Name = $moduleSpec.package.metadata.summary
Version = $moduleSpec.package.metadata.version
}
)
}

# Clear out any inner zip archive objects from memory
if ($zipNuget) {
$zipArch.Dispose()
}

if ($fileNuget) {
$file.Close()
$file.Dispose()
}

[xml] $hotfix = Get-Content -Path "$pathWorkDirectory\HotfixInstallationInfo.xml" -Raw

[PSCustomObject]@{
Platform = $hotfix.HotfixInstallationInfo.PlatformReleaseDisplayName
PlatformVersion = $hotfix.HotfixInstallationInfo.PlatformVersion
Modules = $modules
}

Invoke-TimeSignal -End
}
2 changes: 1 addition & 1 deletion d365fo.tools/functions/set-d365rsatconfiguration.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
$true will make RSAT start adding the operation options in the excel parameter file
$false will stop RSAT from adding the operation options in the excel parameter file
.PARAMETER RSATConfigFilename
Specifies the file name of the RSAT configuration file. Default is 'Microsoft.Dynamics.RegressionSuite.WpfApp.exe.config'
If you are using an older version of RSAT, you might need to change this to 'Microsoft.Dynamics.RegressionSuite.WindowsApp.exe.config'
Expand Down
36 changes: 36 additions & 0 deletions d365fo.tools/tests/functions/Get-D365SDPDetails.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
Describe "Get-D365SDPDetails Unit Tests" -Tag "Unit" {
BeforeAll {
# Place here all things needed to prepare for the tests
}
AfterAll {
# Here is where all the cleanup tasks go
}

Describe "Ensuring unchanged command signature" {
It "should have the expected parameter sets" {
(Get-Command Get-D365SDPDetails).ParameterSets.Name | Should -Be '__AllParameterSets'
}

It 'Should have the expected parameter Path' {
$parameter = (Get-Command Get-D365SDPDetails).Parameters['Path']
$parameter.Name | Should -Be 'Path'
$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 $True
$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0
$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False
$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False
$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False
}
}

Describe "Testing parameterset __AllParameterSets" {
<#
__AllParameterSets -Path
__AllParameterSets -Path
#>
}

}
15 changes: 14 additions & 1 deletion d365fo.tools/tests/functions/Set-D365RsatConfiguration.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,25 @@
$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False
$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False
}
It 'Should have the expected parameter RSATConfigFilename' {
$parameter = (Get-Command Set-D365RsatConfiguration).Parameters['RSATConfigFilename']
$parameter.Name | Should -Be 'RSATConfigFilename'
$parameter.ParameterType.ToString() | Should -Be System.Object
$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 3
$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False
$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False
$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False
}
}

Describe "Testing parameterset __AllParameterSets" {
<#
__AllParameterSets -
__AllParameterSets -LogGenerationEnabled -VerboseSnapshotsEnabled -AddOperatorFieldsToExcelValidationEnabled
__AllParameterSets -LogGenerationEnabled -VerboseSnapshotsEnabled -AddOperatorFieldsToExcelValidationEnabled -RSATConfigFilename
#>
}

Expand Down
97 changes: 97 additions & 0 deletions docs/Get-D365SDPDetails.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
---
external help file: d365fo.tools-help.xml
Module Name: d365fo.tools
online version:
schema: 2.0.0
---

# Get-D365SDPDetails

## SYNOPSIS
Get details from the Software Deployable Package

## SYNTAX

```
Get-D365SDPDetails [-Path] <String> [<CommonParameters>]
```

## DESCRIPTION
Details details about the inner modules / packages that a Software Deployable Contains

## EXAMPLES

### EXAMPLE 1
```
Get-D365SDPDetails -Path 'C:\Temp\RV-10.0.36.44.zip'
```

This will display the basic details about the package.
The package is a zip file.

A result set example:

Platform PlatformVersion Modules
-------- --------------- -------
Update55 7.0.6651.92 {@{Name=RapidValue; Version=7.0.6651.92}, @{Name=TCLCommon; Version=7.0.6651.92}, @{Name=TC...

### EXAMPLE 2
```
Get-D365SDPDetails -Path 'C:\Temp\RV-10.0.36.44'
```

This will display the basic details about the package.
The package is extracted to a local folder.

A result set example:

Platform PlatformVersion Modules
-------- --------------- -------
Update55 7.0.6651.92 {@{Name=RapidValue; Version=7.0.6651.92}, @{Name=TCLCommon; Version=7.0.6651.92}, @{Name=TC...

### EXAMPLE 3
```
Get-D365SDPDetails -Path 'C:\Temp\RV-10.0.36.44.zip' | Select-Object -ExpandProperty Modules
```

This will display the module details that are part of the package.
The package is a zip file.

A result set example:

Name Version
---- -------
RapidValue 7.0.6651.92
TCLCommon 7.0.6651.92
TCLLabel 7.0.6651.92

## PARAMETERS

### -Path
Path to the Software Deployable Package that you want to work against

The cmdlet supports a path to a zip-file or directory with the unpacked content

```yaml
Type: String
Parameter Sets: (All)
Aliases: File

Required: True
Position: 1
Default value: None
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).
## INPUTS
## OUTPUTS
## NOTES
Author: Mötz Jensen (@Splaxi)
## RELATED LINKS
19 changes: 18 additions & 1 deletion docs/Set-D365RsatConfiguration.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Set different RSAT configuration values

```
Set-D365RsatConfiguration [[-LogGenerationEnabled] <Boolean>] [[-VerboseSnapshotsEnabled] <Boolean>]
[[-AddOperatorFieldsToExcelValidationEnabled] <Boolean>] [<CommonParameters>]
[[-AddOperatorFieldsToExcelValidationEnabled] <Boolean>] [[-RSATConfigFilename] <Object>] [<CommonParameters>]
```

## DESCRIPTION
Expand Down Expand Up @@ -99,6 +99,23 @@ Accept pipeline input: False
Accept wildcard characters: False
```
### -RSATConfigFilename
Specifies the file name of the RSAT configuration file.
Default is 'Microsoft.Dynamics.RegressionSuite.WpfApp.exe.config'
If you are using an older version of RSAT, you might need to change this to 'Microsoft.Dynamics.RegressionSuite.WindowsApp.exe.config'
```yaml
Type: Object
Parameter Sets: (All)
Aliases:

Required: False
Position: 4
Default value: Microsoft.Dynamics.RegressionSuite.WpfApp.exe.config
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).
Expand Down

0 comments on commit 05a367c

Please sign in to comment.