[
  {
    "path": ".gitattributes",
    "content": "﻿# Auto detect text files and perform LF normalization\n* text=auto"
  },
  {
    "path": ".github/workflows/Release-Management.yml",
    "content": "on:\n  workflow_dispatch:\n    inputs:\n      gallery_publish:\n        description: \"Publish to the PowerShell Gallery?\"\n        default: true\n        required: false\n        type: boolean\n      github_release:\n        description: \"Create a GitHub release?\"\n        default: true\n        required: false\n        type: boolean\n      module_validation:\n        description: \"Module validation?\"\n        default: true\n        required: false\n        type: boolean\n\njobs:\n  call-tmpl-build-release:\n    uses: fh-inway/d365.psmodule-alm/.github/workflows/tmpl-build-release.yml@main\n    with:\n      module: 'd365fo.tools'\n      skippublish: not(${{ inputs.gallery_publish }})\n      skipghrelease: not(${{ inputs.github_release }})\n      skipValidation: not(${{ inputs.module_validation }})\n    secrets:\n      apikey: ${{ secrets.ApiKey }}"
  },
  {
    "path": ".github/workflows/build-manual.yml",
    "content": "on:\n  workflow_dispatch:\n    inputs:\n      skippublish:\n        description: \"Determines if the publishing to the PowerShell Gallery is skipped\"\n        default: $True\n        required: false\n        type: choice\n        options:\n          - $False\n          - $True\n      skipghrelease:\n        description: \"Determines if creation of a GitHub release is skipped\"\n        default: false\n        required: false\n        type: boolean\n      skipValidation:\n        description: \"Determines if the module validation is skipped\"\n        default: false\n        required: false\n        type: boolean\n\njobs:\n  call-tmpl-build-release:\n    uses: fh-inway/d365.psmodule-alm/.github/workflows/tmpl-build-release.yml@main\n    with:\n      module: 'd365fo.tools'\n      skippublish: ${{ inputs.skippublish }}\n      skipghrelease: ${{ inputs.skipghrelease }}\n      skipValidation: ${{ inputs.skipValidation }}\n    secrets:\n      apikey: ${{ secrets.ApiKey }}"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "# run the Powershell scripts in build folder as part of a GitHub Action\n\nname: d365fo.tools-PR-Test\n\non:\n  push:\n    branches:\n      - master\n  pull_request:\n  workflow_dispatch:\n\njobs:\n\n  prerequisites:\n    name: Prerequisites\n    runs-on: windows-latest\n    steps:\n    - uses: actions/checkout@v4\n    - name: Cache Powershell Modules\n      uses: actions/cache@v4\n      with:\n        path: C:\\Users\\runneradmin\\Documents\\WindowsPowerShell\\Modules\n        key: 20210527|${{ hashFiles('**/vsts-prerequisites.ps1') }}\n    - name: Prerequisites\n      shell: powershell\n      run: build\\vsts-prerequisites.ps1\n\n  general-unit-tests:\n    name: Validate General Unit Tests\n    runs-on: windows-latest\n    needs: prerequisites\n    steps:\n    - uses: actions/checkout@v4\n    - name: Cache Powershell Modules\n      id: cache-powershell-modules\n      uses: actions/cache@v4\n      with:\n        path: C:\\Users\\runneradmin\\Documents\\WindowsPowerShell\\Modules\n        key: 20210527|${{ hashFiles('**/vsts-prerequisites.ps1') }}\n    - name: Prerequisites\n      if: steps.cache-powershell-modules.outputs.cache-hit != 'true'\n      shell: powershell\n      run: build\\vsts-prerequisites.ps1\n    - name: Validate\n      shell: powershell\n      run: build\\vsts-validate.ps1 -TestGeneral $true -TestFunctions $false -Exclude \"PSScriptAnalyzer.Tests.ps1\"\n    - name: Publish Test Results **/TEST-*.xml\n      if: always()\n      uses: EnricoMi/publish-unit-test-result-action/windows@v2\n      with:\n        files: '**/TEST-*.xml'\n        check_name: 'General Unit Tests Results'\n        comment_mode: 'off'\n\n  public-functions-unit-tests:\n    name: Validate Public Functions using PSScriptAnalyzer Unit Tests\n    runs-on: windows-latest\n    needs: prerequisites\n    steps:\n    - uses: actions/checkout@v4\n    - name: Cache Powershell Modules\n      id: cache-powershell-modules\n      uses: actions/cache@v4\n      with:\n        path: C:\\Users\\runneradmin\\Documents\\WindowsPowerShell\\Modules\n        key: 20210527|${{ hashFiles('**/vsts-prerequisites.ps1') }}\n    - name: Prerequisites\n      if: steps.cache-powershell-modules.outputs.cache-hit != 'true'\n      shell: powershell\n      run: build\\vsts-prerequisites.ps1\n    - name: Validate\n      shell: powershell\n      run: build\\vsts-validate-psscriptanalyzer.ps1 -TestPublic $true -TestInternal $false\n    - name: Publish Test Results **/TEST-*.xml\n      if: always()\n      uses: EnricoMi/publish-unit-test-result-action/windows@v2\n      with:\n        files: '**/TEST-*.xml'\n        check_name: 'Public Functions Unit Tests Results'\n        comment_mode: 'off'\n\n  internal-functions-unit-tests:\n    name: Validate Internal Functions using PSScriptAnalyzer Unit Tests\n    runs-on: windows-latest\n    needs: Prerequisites\n    steps:\n    - uses: actions/checkout@v4\n    - name: Cache Powershell Modules\n      id: cache-powershell-modules\n      uses: actions/cache@v4\n      with:\n        path: C:\\Users\\runneradmin\\Documents\\WindowsPowerShell\\Modules\n        key: 20210527|${{ hashFiles('**/vsts-prerequisites.ps1') }}\n    - name: Prerequisites\n      if: steps.cache-powershell-modules.outputs.cache-hit != 'true'\n      shell: powershell\n      run: build\\vsts-prerequisites.ps1\n    - name: Validate\n      shell: powershell\n      run: build\\vsts-validate-psscriptanalyzer.ps1 -TestPublic $false -TestInternal $true\n    - name: Publish Test Results **/TEST-*.xml\n      if: always()\n      uses: EnricoMi/publish-unit-test-result-action/windows@v2\n      with:\n        files: '**/TEST-*.xml'\n        check_name: 'Internal Functions Unit Tests Results'\n        comment_mode: 'off'\n\n  individual-unit-tests:\n    name: Validate Individual Unit Tests\n    runs-on: windows-latest\n    needs: prerequisites\n    steps:\n    - uses: actions/checkout@v4\n    - name: Cache Powershell Modules\n      id: cache-powershell-modules\n      uses: actions/cache@v4\n      with:\n        path: C:\\Users\\runneradmin\\Documents\\WindowsPowerShell\\Modules\n        key: 20210527|${{ hashFiles('**/vsts-prerequisites.ps1') }}\n    - name: Prerequisites\n      if: steps.cache-powershell-modules.outputs.cache-hit != 'true'\n      shell: powershell\n      run: build\\vsts-prerequisites.ps1\n    - name: Validate\n      shell: powershell\n      run: build\\vsts-validate.ps1 -TestGeneral $false -TestFunctions $true\n    - name: Publish Test Results **/TEST-*.xml\n      if: always()\n      uses: EnricoMi/publish-unit-test-result-action/windows@v2\n      with:\n        files: '**/TEST-*.xml'\n        check_name: 'Individual Unit Tests Results'\n        comment_mode: 'off'"
  },
  {
    "path": ".github/workflows/dependencies.yml",
    "content": "# Used to define the dependencies of the d365fo.tools PowerShell module\n# in a way that can be evaluated for the GitHub dependency graph.\n# See https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-the-dependency-graph\n# The actual dependencies are defined in https://github.com/d365collaborative/d365fo.tools/blob/master/d365fo.tools/d365fo.tools.psd1\nname: Dependencies\n\non:\n  workflow_dispatch:\n  \njobs:\n  dependencies:\n    steps:\n      - name: PSFramework\n        uses: PowershellFrameworkCollective/psframework@9b601d25f5831569ec42747be8053d6f6a50723d # version 1.9.308\n      - name: Azure.Storage\n        uses: Azure/azure-powershell@v4.4.0-September2017 # unclear which commit/tag corresponds to https://www.powershellgallery.com/packages/Azure.Storage/4.4.0\n      - name: PSOAuthHelper\n        uses: Splaxi/PSOAuthHelper@837a2da63bf76e86f339a4e43e38df5a3b82affe # version 0.3.0\n      - name: ImportExcel\n        uses: dfinke/ImportExcel@v7.1.0"
  },
  {
    "path": ".github/workflows/update-generated-text.yml",
    "content": "# Run the scrips documented in https://github.com/d365collaborative/d365fo.tools/wiki/Building-tools\n# Creates a pull request with the changes\n\nname: d365fo.tools-Generate-Text\n\non:\n  workflow_dispatch:\n\njobs:\n\n  generateText:\n    name: Generate text\n    runs-on: windows-latest\n    steps:\n    - uses: actions/checkout@v4\n    - name: Cache Powershell Modules\n      id: cache-powershell-modules\n      uses: actions/cache@v4\n      with:\n        path: C:\\Users\\runneradmin\\Documents\\WindowsPowerShell\\Modules\n        key: 20210527|${{ hashFiles('**/vsts-prerequisites.ps1', '**/buildtools.ps1') }}\n    - name: Prerequisites\n      if: steps.cache-powershell-modules.outputs.cache-hit != 'true'\n      shell: powershell\n      run: build\\vsts-prerequisites.ps1\n    - name: BuildTools\n      if: steps.cache-powershell-modules.outputs.cache-hit != 'true'\n      shell: powershell\n      run: build\\buildtools.ps1\n    - name: Format comment based help\n      shell: powershell\n      run: build\\format-commentbasedhelp.ps1\n    - name: Generate parameter unit tests\n      shell: powershell\n      run: build\\generate-parameterunittests.ps1\n    - name: Update documentation\n      shell: powershell\n      run: build\\update-docs.ps1\n    - name: Generate Find-D365Command index\n      shell: powershell\n      run: build\\generate-findcommandindex.ps1\n    - name: Create a pull request for changes\n      uses: peter-evans/create-pull-request@v7\n      with:\n        commit-message: | \n          🤖 Fix best practice deviations\n          \n          This pull request was automatically created by the d365fo.tools-Generate-Text action'\n        title: '🤖 Fix best practice deviations'\n        body: 'This pull request was automatically created by the d365fo.tools-Generate-Text action. See [Building tools](https://github.com/d365collaborative/d365fo.tools/wiki/Building-tools) for more information.'\n        branch: 'update-generated-text/pull-request-patch-for-branch-${{ github.ref_name }}'        "
  },
  {
    "path": ".github/workflows/update-wiki.yml",
    "content": "name: Wiki Update\n\n# Run when contents of the wiki folder are changed\non:\n  push:\n    paths:\n      - 'wiki/**'\n      - 'docs/**'\n    branches:\n      - master\n\n  # Allows you to run this workflow manually from the Actions tab\n  workflow_dispatch:\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Publish wiki folder to repository wiki\n        uses: FH-Inway/github-wiki-publish-action@rsync\n        with:\n          path: \"wiki/ docs\"\n        env:\n          GH_PERSONAL_ACCESS_TOKEN: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "﻿\n# ignore the settings folder and files for VSCode and PSS\n.vscode/*\n*.psproj\n*TempPoint*\n\n# Ignore staging info from Visual Studio\nlibrary/d365fo.tools/.vs/*\nlibrary/d365fo.tools/d365fo.tools/bin/*\nlibrary/d365fo.tools/d365fo.tools/obj/*\n\n# ignore PowerShell Studio MetaData\nd365fo.tools/d365fo.tools.psproj\nd365fo.tools/d365fo.tools.psproj.bak\nd365fo.tools/d365fo.tools.psprojs\nd365fo.tools/d365fo.tools.psproj\n\n# ignore the TestResults\nTestResults/*\n\n# ignore the publishing Directory\npublish/*"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018 Mötz Jensen & Rasmus Andersen\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "﻿# **d365fo.tools**\n\nA PowerShell module to handle different management tasks related to Microsoft Dynamics 365 Finance & Operations (D365FO).\nRead more about D365FO on [docs.microsoft.com](https://docs.microsoft.com/en-us/dynamics365/unified-operations/fin-and-ops/index).\n\nAvailable on PowerShell Gallery:\n[d365fo.tools](https://www.powershellgallery.com/packages/d365fo.tools).\n\n## Table of contents\n* [Getting started](#getting-started)\n* [Getting help](#getting-help)\n* [Contributing](#contributing)\n* [Dependencies](#dependencies)\n\n## Getting started\n### Install the latest module\n```PowerShell\nInstall-Module -Name d365fo.tools\n```\n\n### Install without administrator privileges\n```PowerShell\nInstall-Module -Name d365fo.tools -Scope CurrentUser\n```\n### List all available commands / functions\n\n```PowerShell\nGet-Command -Module d365fo.tools\n```\n\n### Update the module\n\n```PowerShell\nUpdate-Module -name d365fo.tools\n```\n\n### Update the module - force\n\n```PowerShell\nUpdate-Module -name d365fo.tools -Force\n```\n## Getting help\n\n[The wiki](https://github.com/d365collaborative/d365fo.tools/wiki) contains more details about installation and also guides to help you with some common tasks. It also contains documentation for all the module's commands. Expand the wiki's `Pages` control at the top of the content sidebar to view and search the list of command documentation pages.\n\nAnother way to learn about the different cmdlets available is to install the tools onto your D365FO developer box.\nYou can also visit the **'docs'** folder in this repository (look at the top). Click this link [**docs**](https://github.com/d365collaborative/d365fo.tools/tree/master/docs) to jump straight inside.\n\nSince the project started we have adopted and extended the comment based help inside each cmdlet / function. This means that every single command contains at least one fully working example on how to run it and what to expect from the cmdlet.\n\nIf you are just starting out with the module (and maybe with PowerShell as well), consider setting the [`$ConfirmPreference`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables#confirmpreference) to `Medium` or `Low`. This will increase the number of prompts you will receive to confirm executing a command. It will help to avoid accidentally running a command that you didn't intend to run.\n\n**Getting help inside the PowerShell console**\n\nGetting help is as easy as writing **Get-Help CommandName**\n\n```PowerShell\nGet-Help New-D365Bacpac\n```\n\n*This will display the available default help.*\n\nGetting the entire help is as easy as writing **Get-Help CommandName -Full**\n\n```PowerShell\nGet-Help New-D365Bacpac -Full\n```\n\n*This will display all available help content there is for the cmdlet / function*\n\nGetting all the available examples for a given command is as easy as writing **Get-Help CommandName -Examples**\n\n```PowerShell\nGet-Help New-D365Bacpac -Examples\n```\n\n*This will display all the available **examples** for the cmdlet / function.*\n\nWe know that when you are learning about new stuff and just want to share your findings with your peers, working with help inside a PowerShell session isn't that great.\n\n### Web based help and examples\nWe have implemented **platyPS** (https://github.com/PowerShell/platyPS) to generate markdown files for each cmdlet / function available in the module. These files are hosted here on github for you to consume in your web browser and the give you the look and feel of other documentation sites.\n\nThe generated help markdown files are located inside the **'docs'** folder in this repository. Click this [link](https://github.com/d365collaborative/d365fo.tools/tree/master/docs) to jump straight inside.\n\nThey are also available in the [wiki](https://github.com/d365collaborative/d365fo.tools/wiki) in the list of pages.\n\nFor sake of the sanity and just trying to help people out, we copy & pasted **all** the old examples previously available in the readme into the wiki. The page is located [here](https://github.com/d365collaborative/d365fo.tools/wiki/Old-readme-examples). We **don't** plan on keep the **\"Old readme examples\"** wiki up-to-date going forward. If you believe we are missing some examples that should be part of the comment based help, please create an issue.\n\n## Contributing\n\nWant to contribute to the project? We'd love to have you! Visit our [contributing.md](https://github.com/d365collaborative/d365fo.tools/blob/master/contributing.md) for a jump start.\n\n## Dependencies\n\nThis module depends on other modules. The dependencies are documented in the [dependency graph](https://github.com/d365collaborative/d365fo.tools/network/dependencies) and the Dependencies section of the Package Details of the [package listing](https://www.powershellgallery.com/packages/d365fo.tools) in the PowerShell Gallery.\n"
  },
  {
    "path": "build/buildtools.ps1",
    "content": "# Installs the modules required for the automatic text generation.\n# See also https://github.com/d365collaborative/d365fo.tools/wiki/Building-tools\n\nWrite-Host \"Working on the machine named: $($env:computername)\"\nWrite-Host \"The user running is: $($env:UserName)\"\n\n$modules = @(\"PSModuleDevelopment\", \"platyPS\")\n\nforeach ($item in $modules) {\n    \n    $module = Get-InstalledModule -Name $item -ErrorAction SilentlyContinue\n\n    if ($null -eq $module) {\n        Write-Host \"Installing $item\" -ForegroundColor Cyan\n        Install-Module -Name $item -Force -Confirm:$false -Scope CurrentUser -AllowClobber -SkipPublisherCheck\n    }\n    \n    Import-Module $item -Force\n    Get-Module -Name $item\n}"
  },
  {
    "path": "build/filesAfter.txt",
    "content": "﻿# List all files that are loaded in the postimport.ps1\n# In the order they are loaded during postimport\n\ninternal\\configurations\\*.ps1\ninternal\\tepp\\*.tepp.ps1\ninternal\\tepp\\assignment.ps1\ninternal\\scripts\\license.ps1\ninternal\\scripts\\variables.ps1\ninternal\\scripts\\load-dotnet-assemblies.ps1"
  },
  {
    "path": "build/filesBefore.txt",
    "content": "﻿# List all files that are loaded in the preimport.ps1\n# In the order they are loaded during preimport\n\ninternal\\scripts\\enums.ps1\n"
  },
  {
    "path": "build/format-commentbasedhelp.ps1",
    "content": "# Script to format the comments/documentation of the cmdlets used for the commend based help.\n# based on https://gist.github.com/Splaxi/ff7485a24f6ed9937f3e8da76b5d4840\n# See also https://github.com/d365collaborative/d365fo.tools/wiki/Building-tools\n$path = \"$PSScriptRoot\\..\\d365fo.tools\"\n\nfunction Get-Header ($text) {\n    $start = $text.IndexOf('<#')\n    $temp = $start - 2\n    if($temp -gt 0) {\n        $text.SubString(0, $start - 2)\n    }\n    else {\n    \"\"\n    }\n}\n\nfunction Format-Help ($text) {\n    $start = $text.IndexOf('<#')\n    $end = $text.IndexOf('#>')\n    $help = $text.SubString($start + 2, $end - $start - 3)\n    \n    $skipfirst = $null # to avoid trailing spaces\n    foreach ($newline in $help.Split(\"`n\")) {\n        if (-not $skipfirst) { $skipfirst = $true; continue }\n        $trimmed = $newline.Trim()\n        foreach ($line in $trimmed) {\n            if ($line.StartsWith(\".\")) {\n                \"    $line\"\n            }\n            else {\n                \"        $line\"\n            }\n        }\n    }\n}\n\nfunction Get-Body ($text) {\n    $end = $text.IndexOf('#>')\n    $text.SubString($end, $text.Length - $end)\n}\n\n$files = New-Object System.Collections.ArrayList\n$filesPublic = Get-ChildItem -Path \"$path\\functions\\*.ps1\"\n$files.AddRange($filesPublic)\n$filesInternal = Get-ChildItem -Path \"$path\\internal\\functions\\*.ps1\"\n$files.AddRange($filesInternal)\n\nforeach ($file in $files) {\n    $text = ($file | Get-Content -Raw).Trim()\n    Set-Content -Path $file.FullName -Encoding UTF8 -Value (Get-Header $text).TrimEnd()\n    Add-Content -Path $file.FullName -Encoding UTF8 -Value \"<#\".Trim()\n    Add-Content -Path $file.FullName -Encoding UTF8 -Value (Format-Help $text)\n    Add-Content -Path $file.FullName -Encoding UTF8 -Value (Get-Body $text).TrimEnd() -NoNewline\n}"
  },
  {
    "path": "build/generate-findcommandindex.ps1",
    "content": "# Script to generate the comment based markdown help files.\n# See also https://github.com/d365collaborative/d365fo.tools/wiki/Building-tools\n$path = \"$PSScriptRoot\\..\"\n\nImport-Module \"$path\\d365fo.tools\" -Force\n\n$null = Find-D365Command -Rebuild -Verbose"
  },
  {
    "path": "build/generate-parameterunittests.ps1",
    "content": "# Script to generate the parameter unit tests.\n# based on https://gist.github.com/Splaxi/2a24fc3c5193089ae7047ac5b8f104db\n# See also https://github.com/d365collaborative/d365fo.tools/wiki/Building-tools\n$path = \"$PSScriptRoot\\..\\d365fo.tools\"\n\nImport-Module $path -Force\n\n$excludeCommands = @()\n\n$commandsRaw = Get-Command -Module d365fo.tools -CommandType Function\n\nif ($excludeCommands.Count -gt 0) {\n    $commands = $commandsRaw | Select-String -Pattern $excludeCommands -SimpleMatch -NotMatch\n\n} else {\n    $commands = $commandsRaw\n}\n\nRemove-Item -Path \"$path\\tests\\functions\\*.Tests.ps1\"\nforeach ( $commandName in $commands) {\n    Invoke-PSMDTemplate CommandTest -OutPath \"$path\\tests\\functions\" -Name $commandName -Force\n}\n\nGet-ChildItem -Path \"$path\\tests\\functions\" -Recurse -File | Set-PSMDEncoding"
  },
  {
    "path": "build/update-docs.ps1",
    "content": "# Script to generate the comment based markdown help files.\n# based on https://gist.github.com/Splaxi/8934e13cb35918d13af6e3a21c208b0e\n# See also https://github.com/d365collaborative/d365fo.tools/wiki/Building-tools\n$path = \"$PSScriptRoot\\..\"\n\nImport-Module \"$path\\d365fo.tools\" -Force\n\nRemove-Item -Path \"$path\\docs\\*.md\"\n$null = New-MarkdownHelp -Module d365fo.tools -OutputFolder \"$path\\docs\" -Force\n\nGet-ChildItem -Path \"$path\\docs\" -Recurse -File | Set-PSMDEncoding"
  },
  {
    "path": "build/vsts-build.ps1",
    "content": "﻿<#\nThis script publishes the module to the gallery.\nIt expects as input an ApiKey authorized to publish the module.\n\nInsert any build steps you may need to take before publishing it here.\n#>\nparam (\n\t$ModuleName = 'd365fo.tools',\n\n\t$Repository = 'PSGallery',\n\n\t$WorkingDirectory,\n\n\t$ApiKey,\n\n\t[switch]\n\t$SkipPublish,\n\n\t[switch]\n\t$AutoVersion\n)\n\n#region Handle Working Directory Defaults\nif (-not $WorkingDirectory)\n{\n\tif ($env:RELEASE_PRIMARYARTIFACTSOURCEALIAS)\n\t{\n\t\t$WorkingDirectory = Join-Path -Path $env:SYSTEM_DEFAULTWORKINGDIRECTORY -ChildPath $env:RELEASE_PRIMARYARTIFACTSOURCEALIAS\n\t}\n\telse { $WorkingDirectory = $env:SYSTEM_DEFAULTWORKINGDIRECTORY }\n}\nif (-not $WorkingDirectory) { $WorkingDirectory = Split-Path $PSScriptRoot }\n#endregion Handle Working Directory Defaults\n\n# Prepare publish folder\nWrite-PSFMessage -Level Important -Message \"Creating and populating publishing directory\"\n$publishDir = New-Item -Path $WorkingDirectory -Name publish -ItemType Directory\nCopy-Item -Path \"$WorkingDirectory\\$ModuleName\" -Destination $publishDir.FullName -Recurse -Force\n\n# Create commands.ps1\n$text = @()\nGet-ChildItem -Path \"$($publishDir.FullName)\\$ModuleName\\internal\\functions\\\" -Recurse -File -Filter \"*.ps1\" | ForEach-Object {\n\t$text += [System.IO.File]::ReadAllText($_.FullName)\n}\nGet-ChildItem -Path \"$($publishDir.FullName)\\$ModuleName\\functions\\\" -Recurse -File -Filter \"*.ps1\" | ForEach-Object {\n\t$text += [System.IO.File]::ReadAllText($_.FullName)\n}\n$text -join \"`n`n\" | Set-Content -Path \"$($publishDir.FullName)\\$ModuleName\\commands.ps1\"\n\n# Create resourcesBefore.ps1\n$processed = @()\n$text = @()\nforeach ($line in (Get-Content \"$($PSScriptRoot)\\filesBefore.txt\" | Where-Object { $_ -notlike \"#*\" }))\n{\n\tif ([string]::IsNullOrWhiteSpace($line)) { continue }\n\t\n\t$basePath = Join-Path \"$($publishDir.FullName)\\$ModuleName\" $line\n\tforeach ($entry in (Resolve-PSFPath -Path $basePath))\n\t{\n\t\t$item = Get-Item $entry\n\t\tif ($item.PSIsContainer) { continue }\n\t\tif ($item.FullName -in $processed) { continue }\n\t\t$text += [System.IO.File]::ReadAllText($item.FullName)\n\t\t$processed += $item.FullName\n\t}\n}\nif ($text) { $text -join \"`n`n\" | Set-Content -Path \"$($publishDir.FullName)\\$ModuleName\\resourcesBefore.ps1\" }\n\n# Create resourcesAfter.ps1\n$processed = @()\n$text = @()\nforeach ($line in (Get-Content \"$($PSScriptRoot)\\filesAfter.txt\" | Where-Object { $_ -notlike \"#*\" }))\n{\n\tif ([string]::IsNullOrWhiteSpace($line)) { continue }\n\t\n\t$basePath = Join-Path \"$($publishDir.FullName)\\$ModuleName\" $line\n\tforeach ($entry in (Resolve-PSFPath -Path $basePath))\n\t{\n\t\t$item = Get-Item $entry\n\t\tif ($item.PSIsContainer) { continue }\n\t\tif ($item.FullName -in $processed) { continue }\n\t\t$text += [System.IO.File]::ReadAllText($item.FullName)\n\t\t$processed += $item.FullName\n\t}\n}\nif ($text) { $text -join \"`n`n\" | Set-Content -Path \"$($publishDir.FullName)\\$ModuleName\\resourcesAfter.ps1\" }\n\n#region Updating the Module Version\nif ($AutoVersion)\n{\n\tWrite-PSFMessage -Level Important -Message \"Updating module version numbers.\"\n\ttry { [version]$remoteVersion = (Find-Module $ModuleName -Repository $Repository -ErrorAction Stop).Version }\n\tcatch\n\t{\n\t\tStop-PSFFunction -Message \"Failed to access $Repository\" -EnableException $true -ErrorRecord $_\n\t}\n\tif (-not $remoteVersion)\n\t{\n\t\tStop-PSFFunction -Message \"Couldn't find $ModuleName on repository $Repository\" -EnableException $true\n\t}\n\t$newBuildNumber = $remoteVersion.Build + 1\n\t[version]$localVersion = (Import-PowerShellDataFile -Path \"$($publishDir.FullName)\\$ModuleName\\$ModuleName.psd1\").ModuleVersion\n\tUpdate-ModuleManifest -Path \"$($publishDir.FullName)\\$ModuleName\\$ModuleName.psd1\" -ModuleVersion \"$($localVersion.Major).$($localVersion.Minor).$($newBuildNumber)\"\n}\n#endregion Updating the Module Version\n\n# Publish to Gallery\nif ($SkipPublish) { return }\nPublish-Module -Path \"$($publishDir.FullName)\\$ModuleName\" -NuGetApiKey $ApiKey -Force"
  },
  {
    "path": "build/vsts-prerequisites.ps1",
    "content": "﻿Write-Host \"Working on the machine named: $($env:computername)\"\nWrite-Host \"The user running is: $($env:UserName)\"\n\n# $modules = @(\"PSFramework\", \"Az.Storage\", \"AzureAd\", \"PSNotification\", \"PSOAuthHelper\", \"PowerShellGet\", \"PackageManagement\",\"ImportExcel\",\"PSScriptAnalyzer\")\n$modules = @(\"PSFramework\", \"PSScriptAnalyzer\", \"Az.Storage\", \"PSOAuthHelper\", \"ImportExcel\")\n\nWrite-Host \"Installing Pester, maximum version 4.99.99\" -ForegroundColor Cyan\nInstall-Module \"Pester\" -MaximumVersion 4.99.99 -Force -Confirm:$false -Scope CurrentUser -AllowClobber -SkipPublisherCheck\n\nforeach ($item in $modules) {\n    \n    $module = Get-InstalledModule -Name $item -ErrorAction SilentlyContinue\n\n    if ($null -eq $module) {\n        Write-Host \"Installing $item\" -ForegroundColor Cyan\n        Install-Module -Name $item -Force -Confirm:$false -Scope CurrentUser -AllowClobber -SkipPublisherCheck\n    }\n    \n    Import-Module $item -Force\n    Get-Module -Name $item\n}"
  },
  {
    "path": "build/vsts-validate-psscriptanalyzer.ps1",
    "content": "﻿param (\n    $TestPublic = $true,\n\t\n    $TestInternal = $true\n)\n\n# Guide for available variables and working with secrets:\n# https://docs.microsoft.com/en-us/vsts/build-release/concepts/definitions/build/variables?tabs=powershell\n\n# Needs to ensure things are Done Right and only legal commits to master get built\n\n# Run internal pester tests\n\nWrite-Host \"Working on the machine named: $($env:computername)\"\nWrite-Host \"The user running is: $($env:UserName)\"\n\n$modules = @(\"PSFramework\", \"PSScriptAnalyzer\", \"Az.Storage\", \"PSOAuthHelper\", \"ImportExcel\")\n\nforeach ($item in $modules) {\n    $module = Get-Module -Name $item -ErrorAction SilentlyContinue\n\n    if ($null -eq $module) {\n        Write-Host \"Importing $item\" -ForegroundColor Cyan\n        Import-Module $item -Force\n    }\n}\n\nImport-Module \"Pester\" -MaximumVersion 4.99.99 -Force\n\n& \"$PSScriptRoot\\..\\d365fo.tools\\tests\\pester-PSScriptAnalyzer.ps1\" -TestPublic $TestPublic -TestInternal $TestInternal"
  },
  {
    "path": "build/vsts-validate.ps1",
    "content": "﻿param (\n    $TestGeneral = $true,\n\t\n    $TestFunctions = $true,\n\n\t$Exclude = \"\"\n\n)\n\n# Guide for available variables and working with secrets:\n# https://docs.microsoft.com/en-us/vsts/build-release/concepts/definitions/build/variables?tabs=powershell\n\n# Needs to ensure things are Done Right and only legal commits to master get built\n\n# Run internal pester tests\n\nWrite-Host \"Working on the machine named: $($env:computername)\"\nWrite-Host \"The user running is: $($env:UserName)\"\n\n$modules = @(\"PSFramework\", \"PSScriptAnalyzer\", \"Az.Storage\", \"PSOAuthHelper\", \"ImportExcel\")\n\nforeach ($item in $modules) {\n    $module = Get-Module -Name $item -ErrorAction SilentlyContinue\n\n    if ($null -eq $module) {\n        Write-Host \"Importing $item\" -ForegroundColor Cyan\n        Import-Module $item -Force\n    }\n}\n\nImport-Module \"Pester\" -MaximumVersion 4.99.99 -Force\n\n& \"$PSScriptRoot\\..\\d365fo.tools\\tests\\pester.ps1\" -TestGeneral $TestGeneral -TestFunctions $TestFunctions -Exclude $Exclude"
  },
  {
    "path": "contributing.md",
    "content": "﻿Here, we'll help you understand how to contribute to the project, and talk about fun stuff like styles and guidelines.\n# Contributing\nLet's sum this up saying that we'd **LOVE** your help. We're slowly getting the hang of running an open source project of this size but we're still learning along the way.\n\nThere are several ways to contribute:\n - Create new commands (PowerShell/Dynamics 365 for Finance & Operations knowledge required)\n - Report bugs (everyone can do it)\n - Tests (Pester knowledge required)\n - Documentation: functions, website, this guide, everything can be improved (everyone can)\n - Code review (PowerShell/Dynamics 365 for Finance & Operations knowledge required)\n\nIf you wanna help out to make the module even more robust\n   - Standardize param names\n   - Create tests for existing functions\n   - Review existing function documentation\n\n## Documentation\nDocumentation is really the area we welcome any help possible. The documentation refers to CBH (Comment Based Help). The CBH documentation is included with each command and is the content you see when you run `Get-Help Function-Name`. If any of that content is not clear enough or if the examples in the functions are not working, you should say so (e.g. raise an issue on GitHub or contact us on twitter). Even if you are a casual user or a PowerShell newbie, we need your angle to make it as straight forward and clear as possible.\n\n## Contribute New Commands\nStart out reviewing the [list of functions on in the docs folder](https://github.com/d365collaborative/d365fo.tools/tree/master/docs), or pulling the list from the module with `Get-Command -Module d365fo.tools -CommandType Function | Out-GridView`. If you find something similar already exists, open [a new issue on GitHub](https://github.com/d365collaborative/d365fo.tools/issues/new) to request an enhancement to that command. If nothing similar pops up, either ping @splaxi on twitter with your idea about the new command or open a new issue on GitHub with details or requirements you need.\n\n## Report Bugs\n[Open a new issue](https://github.com/d365collaborative/d365fo.tools/issues/new) on GitHub and fill in all the details. The title should report the affected function, followed by a brief description (e.g. _Get-D365Environment - Add property x to default view_). The provided template holds most of the details coders need to fix the issue.\n\n## Fix Bugs\nIf you feel for fixing a bug, but don't know GitHub enough, the dbatools.io project has a good starting guide. We are on the same team, so instead of us writing a guide that is close to theirs - we simply point to theirs [step-by-step guide](https://dbatools.io/firstpull).\n\n[Open a PR](https://github.com/d365collaborative/d365fo.tools/pulls) targeting ideally just one ps1 file (the PR needs to target the *master* branch), with the name of the function being fixed as a title. Everyone will chime in reviewing the code and either approve the PR or request changes. The more targeted and focused the PR, the easier to merge, the fastest to go into the next release. Keep them as simple as possible to speed up the process.\n\n## Branching\nMake sure to read our [branching guide](https://github.com/d365collaborative/d365fo.tools/wiki/Branching) on the wiki to get a good starting point.\n\n## Automated build\nIf you want to get early warning about what you need to fix in the PR you want to create, you could configure your own Azure DevOps account to build from your own Github repository. Read the guide on how to utilize the same build steps as we are [here](https://github.com/d365collaborative/d365fo.tools/wiki/Azure-DevOps-Build-Configuration)\n\n\n## Standardize Parameters and Variables\nWe chose to follow the standards below when creating parameters and variables for a function:\n\n1) Any variable used in the parameter block must have first letter of each word capitalized. (e.g. `$FilePath`, `$BacpacPath`). This is also called [PascalCase](https://en.wikipedia.org/wiki/Camel_case).\n2) Any variable used in the parameter block **is required** to be singular.\n3) Any variable not part of the parameter block, that is multiple words, will follow the camelCase format. (e.g. `$currentFile`, `$hotfixManifest`)\n4) Refrain from using single character variable names (e.g. `$i` or `$x`). Try to make them \"readable\" in the sense that if someone sees the variable name they can get a hint what it presents (e.g. `$db`, `$operatorName`).\n\nWhen you are working with \"objects\" in D365FO, say with files, what variable name you use should be based on what operation you are doing. You can find examples of various situations in the current code of the module to see more detailed examples. As an example: in situations where you are looping over the files for a folder, try to use a plural variable name for the collection and then single or abbreviated name in the loop for each object of that collection. e.g. `foreach ($file in $files) {...`.\n\n## Tests\nRemember that tests are needed to make sure d365fo.tools code behaves properly. The ultimate goal is for any user to be able to run d365fo.tools' tests within their environment and, depending on the result, be sure everything works as expected. d365fo.tools works on a matrix of environments that will hardly be fully covered by a Continuous Integration system. That being said, we have Azure DevOps set up to run at each and every commit.\n\n### How to write tests\nTo save resources and be more flexible, we split tests with tags into two main categories, \"UnitTests\" and \"IntegrationTests\". Below is a starting list of things to consider when writing your test:\n- \"UnitTests\" do not require an instance to be up and running, and are easily the most flexible to be ran on every user computer. - \"IntegrationTests\" instead require one or more active instances, and there is a bit of setup to do in order to run them.\n- Every one of the \"IntegrationTests\" may need to create a resource (e.g. a database).\n- Every resource should be named with the \"d365fo.toolsci_\" prefix. _The test should attempt to clean up after itself leaving a pristine environment._\n- Try to write tests thinking they may run in each and every user's test environment.\n\nThe d365fo.tools-templates repository holds examples, but you can also inspect/copy/cannibalize existing tests. You'll see that every test file is named with a simple convention _Verb-Noun*.Tests.ps1_, and this is required by [Pester](https://GitHub.com/pester/Pester), which is the de-facto standard for running tests in PowerShell.\n\nTests make sure a \"contract\" is made between the code and its behavior: once a test is formalized, changes to the code itself or enhancement will be written making sure existing functionality is retained, making the entire d365fo.tools experience more stable.\n\n**Note:** This entire page is deeply inspired by the work done over in the [dbatool.io](https://github.com/sqlcollaborative/dbatools) module. Pay them a visit and learn from the very same people as we did."
  },
  {
    "path": "d365fo.tools/bin/d365fo.tools-index.json",
    "content": "﻿[\n    {\n        \"CommandName\":  \"Add-D365AzureStorageConfig\",\n        \"Description\":  \"Adds an Azure Storage Account config to the configuration store\",\n        \"Tags\":  [\n                     \"Azure\",\n                     \"Azure Storage\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"Token\",\n                     \"Blob\",\n                     \"Container\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"The logical name of the Azure Storage Account you are about to registered in the configuration store\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"AccountId\",\n                           \"The account id for the Azure Storage Account you want to register in the configuration store\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"AccessToken\",\n                           \"The access token for the Azure Storage Account you want to register in the configuration store\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"SAS\",\n                           \"The SAS key that you have created for the storage account or blob container\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Container\",\n                           \"The name of the blob container inside the Azure Storage Account you want to register in the configuration store\",\n                           \"Blobname,Blob\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Temporary\",\n                           \"Instruct the cmdlet to only temporarily add the azure storage account configuration in the configuration store\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Switch to instruct the cmdlet to overwrite already registered Azure Storage Account entry\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Save an Azure Storage Account config\",\n        \"Name\":  \"Add-D365AzureStorageConfig\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eAdd-D365AzureStorageConfig -Name \\\"UAT-Exports\\\" -AccountId \\\"1234\\\" -AccessToken \\\"dafdfasdfasdf\\\" -Container \\\"testblob\\\"\\nThis will add an entry into the list of Azure Storage Accounts that is stored with the name \\\"UAT-Exports\\\" with AccountId \\\"1234\\\", AccessToken \\\"dafdfasdfasdf\\\" and blob container \\\"testblob\\\".\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eAdd-D365AzureStorageConfig -Name UAT-Exports -SAS \\\"sv2018-03-28\\u0026siunlisted\\u0026src\\u0026sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\\\" -AccountId \\\"1234\\\" -Container \\\"testblob\\\"\\nThis will add an entry into the list of Azure Storage Accounts that is stored with the name \\\"UAT-Exports\\\" with AccountId \\\"1234\\\", SAS \\r\\n\\\"sv=2018-03-28\\u0026si=unlisted\\u0026sr=c\\u0026sig=AUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\\\" and blob container \\\"testblob\\\".\\r\\nThe SAS key enables you to provide explicit access to a given blob container inside an Azure Storage Account.\\r\\nThe SAS key can easily be revoked and that way you have control over the access to the container and its content.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eAdd-D365AzureStorageConfig -Name UAT-Exports -SAS \\\"sv2018-03-28\\u0026siunlisted\\u0026src\\u0026sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\\\" -AccountId \\\"1234\\\" -Container \\\"testblob\\\" -Temporary\\nThis will add an entry into the list of Azure Storage Accounts that is stored with the name \\\"UAT-Exports\\\" with AccountId \\\"1234\\\", SAS \\r\\n\\\"sv=2018-03-28\\u0026si=unlisted\\u0026sr=c\\u0026sig=AUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\\\" and blob container \\\"testblob\\\".\\r\\nThe SAS key enables you to provide explicit access to a given blob container inside an Azure Storage Account.\\r\\nThe SAS key can easily be revoked and that way you have control over the access to the container and its content.\\nThe configuration will only last for the rest of this PowerShell console session.\",\n        \"Syntax\":  \"Add-D365AzureStorageConfig -Name \\u003cString\\u003e -AccountId \\u003cString\\u003e -AccessToken \\u003cString\\u003e -Container \\u003cString\\u003e [-Temporary] [-Force] [\\u003cCommonParameters\\u003e]\\nAdd-D365AzureStorageConfig -Name \\u003cString\\u003e -AccountId \\u003cString\\u003e -SAS \\u003cString\\u003e -Container \\u003cString\\u003e [-Temporary] [-Force] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Add-D365BroadcastMessageConfig\",\n        \"Description\":  \"Adds a broadcast message config to the configuration store\",\n        \"Tags\":  [\n                     \"Servicing\",\n                     \"Broadcast\",\n                     \"Message\",\n                     \"Users\",\n                     \"Environment\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"ClientId\",\n                     \"ClientSecret\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"The logical name of the broadcast configuration you are about to register in the configuration store\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Tenant\",\n                           \"Azure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to send a message to\",\n                           \"$AADGuid\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"URL\",\n                           \"URL / URI for the D365FO environment you want to send a message to\",\n                           \"URI\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ClientId\",\n                           \"The ClientId obtained from the Azure Portal when you created a Registered Application\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ClientSecret\",\n                           \"The ClientSecret obtained from the Azure Portal when you created a Registered Application\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"TimeZone\",\n                           \"Id of the Time Zone your environment is running in\\nYou might experience that the local VM running the D365FO is running another Time Zone than the computer you are running this cmdlet from\\nAll available .NET Time Zones can be traversed with tab for this parameter\\nThe default value is \\\"UTC\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"UTC\"\n                       ],\n                       [\n                           \"EndingInMinutes\",\n                           \"Specify how many minutes into the future you want this message / maintenance window to last\\nDefault value is 60 minutes\\nThe specified StartTime will always be based on local Time Zone. If you specify a different Time Zone than the local computer is running, the start and end time will be calculated based on your \\r\\nselection.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"60\"\n                       ],\n                       [\n                           \"OnPremise\",\n                           \"Specify if environnement is an D365 OnPremise\\nDefault value is \\\"Not set\\\" (= Cloud Environnement)\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Temporary\",\n                           \"Instruct the cmdlet to only temporarily add the broadcast message configuration in the configuration store\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Instruct the cmdlet to overwrite the broadcast message configuration with the same name\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Save a broadcast message config\",\n        \"Name\":  \"Add-D365BroadcastMessageConfig\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eAdd-D365BroadcastMessageConfig -Name \\\"UAT\\\" -Tenant \\\"e674da86-7ee5-40a7-b777-1111111111111\\\" -URL \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\" -ClientId \\r\\n\\\"dea8d7a9-1602-4429-b138-111111111111\\\" -ClientSecret \\\"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\\\"\\nThis will create a new broadcast message configuration with the name \\\"UAT\\\".\\r\\nIt will save \\\"e674da86-7ee5-40a7-b777-1111111111111\\\" as the Azure Active Directory guid.\\r\\nIt will save \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\" as the D365FO environment.\\r\\nIt will save \\\"dea8d7a9-1602-4429-b138-111111111111\\\" as the ClientId.\\r\\nIt will save \\\"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\\\" as ClientSecret.\\r\\nIt will use the default value \\\"UTC\\\" Time Zone for converting the different time and dates.\\r\\nIt will use the default end time which is 60 minutes.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eAdd-D365BroadcastMessageConfig -Name \\\"UAT\\\" -OnPremise -Tenant \\\"https://adfs.local/adfs\\\" -URL \\\"https://ax-sandbox.d365fo.local\\\" -ClientId \\\"dea8d7a9-1602-4429-b138-111111111111\\\" -ClientSecret \\r\\n\\\"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\\\"\\nThis will create a new broadcast message configuration with the name \\\"UAT\\\".\\r\\nIt will target an OnPremise environment.\\r\\nIt will save \\\"https://adfs.local/adfs\\\" as the OAuth Tenant Provider.\\r\\nIt will save \\\"https://ax-sandbox.d365fo.local\\\" as the D365FO environment.\\r\\nIt will save \\\"dea8d7a9-1602-4429-b138-111111111111\\\" as the ClientId.\\r\\nIt will save \\\"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\\\" as ClientSecret.\\r\\nIt will use the default value \\\"UTC\\\" Time Zone for converting the different time and dates.\\r\\nIt will use the default end time which is 60 minutes.\",\n        \"Syntax\":  \"Add-D365BroadcastMessageConfig [-Name] \\u003cString\\u003e [[-Tenant] \\u003cString\\u003e] [[-URL] \\u003cString\\u003e] [[-ClientId] \\u003cString\\u003e] [[-ClientSecret] \\u003cString\\u003e] [[-TimeZone] \\u003cString\\u003e] [[-EndingInMinutes] \\u003cInt32\\u003e] [-OnPremise] [-Temporary] [-Force] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Add-D365ModuleToRemove\",\n        \"Description\":  \"Modifies an existing deployable package and adds a ModuleToRemove.txt file to it.\",\n        \"Params\":  [\n                       [\n                           \"ModuleToRemove\",\n                           \"Path to the ModuleToRemove.txt file that you want to have inside a deployable package\",\n                           \"\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"DeployablePackage\",\n                           \"Path to the deployable package file where the ModuleToRemove.txt file should be added\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"OutputPath\",\n                           \"Path where you want the generated deployable package to be stored\\nDefault value is the same as the \\\"DeployablePackage\\\" parameter\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$DeployablePackage\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Florian Hopfner (@FH-Inway)\",\n        \"Synopsis\":  \"Adds a ModuleToRemove.txt file to a deployable package\",\n        \"Name\":  \"Add-D365ModuleToRemove\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eAdd-D365ModuleToRemove -ModuleToRemove \\\"C:\\\\temp\\\\ModuleToRemove.txt\\\" -DeployablePackage \\\"C:\\\\temp\\\\DeployablePackage.zip\\\"\\nThis will take the \\\"C:\\\\temp\\\\ModuleToRemove.txt\\\" file and add it to the \\\"C:\\\\temp\\\\DeployablePackage.zip\\\" deployable package in the \\\"AOSService/Scripts\\\" folder.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eNew-D365ModuleToRemove -Path C:\\\\Temp -Modules \\\"MyRemovedModule1\\\",\\\"MySecondRemovedModule\\\" | Add-D365ModuleToRemove -DeployablePackage C:\\\\Temp\\\\DeployablePackage.zip\\nThis will create a new ModuleToRemove.txt file and fill in \\\"MyRemovedModule1\\\" and \\\"MySecondRemovedModule\\\" as the modules to remove. The file is then added to the \\\"C:\\\\Temp\\\\DeployablePackage.zip\\\" \\r\\ndeployable package.\",\n        \"Syntax\":  \"Add-D365ModuleToRemove [-ModuleToRemove] \\u003cString\\u003e [-DeployablePackage] \\u003cString\\u003e [-OutputPath \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Add-D365RsatWifConfigAuthorityThumbprint\",\n        \"Description\":  \"Register a certificate thumbprint in the wif.config file.\\nThis can be useful for example when configuring RSAT on a local machine and add the used certificate thumbprint to that AOS.s\",\n        \"Tags\":  [\n                     \"RSAT\",\n                     \"Certificate\",\n                     \"Testing\",\n                     \"Regression Suite Automation Test\",\n                     \"Regression\",\n                     \"Test\",\n                     \"Automation\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"CertificateThumbprint\",\n                           \"The thumbprint value of the certificate that you want to register in the wif.config file\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"Add-D365WIFConfigAuthorityThumbprint\",\n        \"Author\":  \"Kenny Saelen (@kennysaelen)\",\n        \"Synopsis\":  \"Add a certificate thumbprint to the wif.config.\",\n        \"Name\":  \"Add-D365RsatWifConfigAuthorityThumbprint\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eAdd-D365RsatWifConfigAuthorityThumbprint -CertificateThumbprint \\\"12312323r424\\\"\\nThis will open the wif.config file and insert the \\\"12312323r424\\\" thumbprint value into the file.\",\n        \"Syntax\":  \"Add-D365RsatWifConfigAuthorityThumbprint [-CertificateThumbprint] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Add-D365WindowsDefenderRules\",\n        \"Description\":  \"Add rules to the Windows Defender to exclude Visual Studio, D365 Batch process, D365 Sync process, XPP related processes and SQL Server processes from scans and monitoring.\\nThis will lead to performance gains because the Windows Defender stops to scan every file accessed by e.g. the MSBuild process, the cache and things around Visual Studio.\\nSupports rules for VS 2015 and VS 2019.\",\n        \"Tags\":  [\n                     \"DevTools\",\n                     \"Developer\",\n                     \"Performance\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Silent\",\n                           \"Instruct the cmdlet to silence the output written to the console\\nIf set the output will be silenced, if not set, the output will be written to the console\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Robin Kretzschmar (@darksmile92)\",\n        \"Synopsis\":  \"Add rules to Windows Defender to enhance performance during development.\",\n        \"Name\":  \"Add-D365WindowsDefenderRules\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eAdd-D365WindowsDefenderRules\\nThis will add the most common rules to the Windows Defender as exceptions.\\r\\nAll output will be written to the console.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eAdd-D365WindowsDefenderRules -Silent\\nThis will add the most common rules to the Windows Defender as exceptions.\\r\\nAll output will be silenced and not outputted to the console.\",\n        \"Syntax\":  \"Add-D365WindowsDefenderRules [-Silent] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Backup-D365DevConfig\",\n        \"Description\":  \"Will backup the DynamicsDevConfig.xml file located in the PackagesLocalDirectory\\\\Bin folder\",\n        \"Tags\":  [\n                     \"Web Server\",\n                     \"IIS\",\n                     \"IIS Express\",\n                     \"Development\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path to the folder where you want the DynamicsDevConfig.xml file to be persisted\\nDefault is: \\\"C:\\\\Temp\\\\d365fo.tools\\\\DevConfigBackup\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path $Script:DefaultTempPath \\\"DevConfigBackup\\\")\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Instructs the cmdlet to overwrite the destination file if it already exists\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Sander Holvoet (@smholvoet)\",\n        \"Synopsis\":  \"Backup the DynamicsDevConfig.xml file\",\n        \"Name\":  \"Backup-D365DevConfig\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eBackup-D365DevConfig\\nWill locate the DynamicsDevConfig.xml file, and back it up.\\r\\nIt will look for the file in the PackagesLocalDirectory\\\\Bin folder. E.g. K:\\\\AosService\\\\PackagesLocalDirectory\\\\Bin\\\\DynamicsDevConfig.xml.\\r\\nIt will save the file to the default location: \\\"C:\\\\Temp\\\\d365fo.tools\\\\DevConfigBackup\\\".\\nA result set example:\\nFilename              LastModified         File\\r\\n--------              ------------         ----\\r\\nDynamicsDevConfig.xml 6/29/2021 7:31:04 PM C:\\\\temp\\\\d365fo.tools\\\\DevConfigBackup\\\\DynamicsDevConfig.xml\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eBackup-D365DevConfig -Force\\nWill locate the DynamicsDevConfig.xml file, back it up, and overwrite if a previous backup file exists.\\r\\nIt will look for the file in the PackagesLocalDirectory\\\\Bin folder. E.g. K:\\\\AosService\\\\PackagesLocalDirectory\\\\Bin\\\\DynamicsDevConfig.xml.\\r\\nIt will save the file to the default location: \\\"C:\\\\Temp\\\\d365fo.tools\\\\DevConfigBackup\\\".\\r\\nIt will overwrite any file named DynamicsDevConfig.xml in the destination folder.\\nA result set example:\\nFilename              LastModified         File\\r\\n--------              ------------         ----\\r\\nDynamicsDevConfig.xml 6/29/2021 7:31:04 PM C:\\\\temp\\\\d365fo.tools\\\\DevConfigBackup\\\\DynamicsDevConfig.xml\",\n        \"Syntax\":  \"Backup-D365DevConfig [[-OutputPath] \\u003cString\\u003e] [-Force] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Backup-D365MetaDataDir\",\n        \"Description\":  \"Creates a backup of all the files and folders from the Metadata directory\",\n        \"Tags\":  [\n                     \"PackagesLocalDirectory\",\n                     \"MetaData\",\n                     \"MetaDataDir\",\n                     \"MeteDataDirectory\",\n                     \"Backup\",\n                     \"Development\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"MetaDataDir\",\n                           \"Path to the Metadata directory\\nDefault value is the PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:MetaDataDir\\\"\"\n                       ],\n                       [\n                           \"BackupDir\",\n                           \"Path where you want the backup to be place\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$($Script:MetaDataDir)_backup\\\"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Create a backup of the Metadata directory\",\n        \"Name\":  \"Backup-D365MetaDataDir\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eBackup-D365MetaDataDir\\nThis will backup the PackagesLocalDirectory and create an PackagesLocalDirectory_backup next to it\",\n        \"Syntax\":  \"Backup-D365MetaDataDir [[-MetaDataDir] \\u003cString\\u003e] [[-BackupDir] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Backup-D365Runbook\",\n        \"Description\":  \"Backup a runbook file for you to persist it for later analysis\",\n        \"Tags\":  [\n                     \"Runbook\",\n                     \"Backup\",\n                     \"Analysis\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"File\",\n                           \"Path to the file you want to backup\",\n                           \"Path\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"DestinationPath\",\n                           \"Path to the folder where you want the backup file to be placed\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path $Script:DefaultTempPath \\\"RunbookBackups\\\")\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Instructs the cmdlet to overwrite the destination file if it already exists\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Backup a runbook file\",\n        \"Name\":  \"Backup-D365Runbook\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eBackup-D365Runbook -File \\\"C:\\\\DynamicsAX\\\\InstallationRecords\\\\Runbooks\\\\Runbook_20190327.xml\\\"\\nThis will backup the \\\"C:\\\\DynamicsAX\\\\InstallationRecords\\\\Runbooks\\\\Runbook_20190327.xml\\\".\\r\\nThe default destination folder is used, \\\"c:\\\\temp\\\\d365fo.tools\\\\runbookbackups\\\\\\\".\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eBackup-D365Runbook -File \\\"C:\\\\DynamicsAX\\\\InstallationRecords\\\\Runbooks\\\\Runbook_20190327.xml\\\" -Force\\nThis will backup the \\\"C:\\\\DynamicsAX\\\\InstallationRecords\\\\Runbooks\\\\Runbook_20190327.xml\\\".\\r\\nThe default destination folder is used, \\\"c:\\\\temp\\\\d365fo.tools\\\\runbookbackups\\\\\\\".\\r\\nIf the file already exists in the destination folder, it will be overwritten.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365Runbook | Backup-D365Runbook\\nThis will backup all runbook files found with the \\\"Get-D365Runbook\\\" cmdlet.\\r\\nThe default destination folder is used, \\\"c:\\\\temp\\\\d365fo.tools\\\\runbookbackups\\\\\\\".\",\n        \"Syntax\":  \"Backup-D365Runbook [-File] \\u003cString\\u003e [[-DestinationPath] \\u003cString\\u003e] [-Force] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Backup-D365WebConfig\",\n        \"Description\":  \"Will backup the web.config file located in the AOS / IIS folder\",\n        \"Tags\":  [\n                     \"DEV\",\n                     \"Tier2\",\n                     \"DB\",\n                     \"Database\",\n                     \"Debug\",\n                     \"JIT\",\n                     \"LCS\",\n                     \"Azure DB\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path to the folder where you want the web.config file to be persisted\\nDefault is: \\\"C:\\\\Temp\\\\d365fo.tools\\\\WebConfigBackup\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path $Script:DefaultTempPath \\\"WebConfigBackup\\\")\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Instructs the cmdlet to overwrite the destination file if it already exists\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Backup the web.config file\",\n        \"Name\":  \"Backup-D365WebConfig\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eBackup-D365WebConfig\\nWill locate the web.config file, and back it up.\\r\\nIt will look for the file in the AOS / IIS folder. E.g. K:\\\\AosService\\\\WebRoot\\\\web.config.\\r\\nIt will save the file to the default location: \\\"C:\\\\Temp\\\\d365fo.tools\\\\WebConfigBackup\\\".\\nA result set example:\\nFilename   LastModified         File\\r\\n--------   ------------         ----\\r\\nweb.config 6/29/2021 7:31:04 PM C:\\\\temp\\\\d365fo.tools\\\\WebConfigBackup\\\\web.config\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eBackup-D365WebConfig -Force\\nWill locate the web.config file, back it up, and overwrite if a previous backup file exists.\\r\\nIt will look for the file in the AOS / IIS folder. E.g. K:\\\\AosService\\\\WebRoot\\\\web.config.\\r\\nIt will save the file to the default location: \\\"C:\\\\Temp\\\\d365fo.tools\\\\WebConfigBackup\\\".\\r\\nIt will overwrite any file named web.config in the destination folder.\\nA result set example:\\nFilename   LastModified         File\\r\\n--------   ------------         ----\\r\\nweb.config 6/29/2021 7:31:04 PM C:\\\\temp\\\\d365fo.tools\\\\WebConfigBackup\\\\web.config\",\n        \"Syntax\":  \"Backup-D365WebConfig [[-OutputPath] \\u003cString\\u003e] [-Force] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Backup-D365WifConfig\",\n        \"Description\":  \"Will backup the wif.config file located in the AOS / IIS folder\",\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path to the folder where you want the web.config file to be persisted\\nDefault is: \\\"C:\\\\Temp\\\\d365fo.tools\\\\WifConfigBackup\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path $Script:DefaultTempPath \\\"WifConfigBackup\\\")\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Instructs the cmdlet to overwrite the destination file if it already exists\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Florian Hopfner (@FH-Inway)\",\n        \"Synopsis\":  \"Backup the wif.config file\",\n        \"Name\":  \"Backup-D365WifConfig\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eBackup-D365WifConfig\\nWill locate the wif.config file, and back it up.\\r\\nIt will look for the file in the AOS / IIS folder. E.g. K:\\\\AosService\\\\WebRoot\\\\wif.config.\\r\\nIt will save the file to the default location: \\\"C:\\\\Temp\\\\d365fo.tools\\\\WifConfigBackup\\\".\\nA result set example:\\nFilename   LastModified         File\\r\\n--------   ------------         ----\\r\\nwif.config 6/29/2021 7:31:04 PM C:\\\\temp\\\\d365fo.tools\\\\WifConfigBackup\\\\wif.config\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eBackup-D365WifConfig -Force\\nWill locate the wif.config file, back it up, and overwrite if a previous backup file exists.\\r\\nIt will look for the file in the AOS / IIS folder. E.g. K:\\\\AosService\\\\WebRoot\\\\wif.config.\\r\\nIt will save the file to the default location: \\\"C:\\\\Temp\\\\d365fo.tools\\\\WifConfigBackup\\\".\\r\\nIt will overwrite any file named wif.config in the destination folder.\\nA result set example:\\nFilename   LastModified         File\\r\\n--------   ------------         ----\\r\\nwif.config 6/29/2021 7:31:04 PM C:\\\\temp\\\\d365fo.tools\\\\WifConfigBackup\\\\wif.config\",\n        \"Syntax\":  \"Backup-D365WifConfig [[-OutputPath] \\u003cString\\u003e] [-Force] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Clear-D365ActiveBroadcastMessageConfig\",\n        \"Description\":  \"Clear the active broadcast message config from the configuration store\",\n        \"Tags\":  [\n                     \"Servicing\",\n                     \"Broadcast\",\n                     \"Message\",\n                     \"Users\",\n                     \"Environment\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"ClientId\",\n                     \"ClientSecret\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Temporary\",\n                           \"Instruct the cmdlet to only temporarily clear the active broadcast message configuration in the configuration store\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Clear the active broadcast message config\",\n        \"Name\":  \"Clear-D365ActiveBroadcastMessageConfig\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eClear-D365ActiveBroadcastMessageConfig\\nThis will clear the active broadcast message configuration from the configuration store.\",\n        \"Syntax\":  \"Clear-D365ActiveBroadcastMessageConfig [-Temporary] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Clear-D365BacpacObject\",\n        \"Description\":  \"Remove a set of sql objects from inside a bacpac/dacpac or zip file, before restoring it into your SQL Server / Azure SQL DB\\n\\nIt will open the file as a zip archive, locate the desired sql object and remove it, so when importing the bacpac the object will not be created\\n\\nThe default behavior is that you get a copy of the file, where the desired sql objects are removed\",\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the bacpac/dacpac or zip file that you want to work against\",\n                           \"BacpacFile,File\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Name\",\n                           \"Name of the sql object that you want to remove\\nSupports an array of names\\nIf a schema name isn\\u0027t supplied as part of the table name, the cmdlet will prefix it with \\\"dbo.\\\"\\nSome sql objects are 3 part named, which will require that you fill them in with brackets E.g. [dbo].[SalesTable].[CustomIndexName1]\\r\\n- Index\\r\\n- Constraints\",\n                           \"ObjectName\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ObjectType\",\n                           \"Instruct the cmdlet, the type of object that you want to remove\\nAs we are manipulating the bacpac file, we can only handle 1 ObjectType per run\\nIf you want to remove SqlView and SqlIndex, you will have to run the cmdlet 1 time for SqlViews and 1 time for SqlIndex\\nSupported types are:\\r\\n\\\"SqlView\\\", \\\"SqlTable\\\", \\\"SqlIndex\\\", \\\"SqlCheckConstraint\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the updated bacpac/dacpac or zip file to be saved\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ClearFromSource\",\n                           \"Instruct the cmdlet to delete sql objects directly from the source file\\nIt will save disk space and time, because it doesn\\u0027t have to create a copy of the bacpac file, before deleting sql objects from it\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Synopsis\":  \"Clear out sql objects from inside the bacpac/dacpac or zip file\",\n        \"Name\":  \"Clear-D365BacpacObject\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eClear-D365BacpacObject -Path \\\"C:\\\\Temp\\\\AxDB.bacpac\\\" -ObjectType SqlView -Name \\\"View2\\\" -OutputPath \\\"C:\\\\Temp\\\\AXBD_Cleaned.bacpac\\\"\\nThis will remove the SqlView \\\"View2\\\" from inside the bacpac file.\\nIt uses \\\"C:\\\\Temp\\\\AxDB.bacpac\\\" as the Path for the bacpac file.\\r\\nIt uses \\\"View2\\\" as the name of the object to delete.\\r\\nIt uses \\\"C:\\\\Temp\\\\AXBD_Cleaned.bacpac\\\" as the OutputPath to where it will store the updated bacpac file.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eClear-D365BacpacObject -Path \\\"C:\\\\Temp\\\\AxDB.bacpac\\\" -ObjectType SqlView -Name \\\"dbo.View1\\\",\\\"View2\\\" -OutputPath \\\"C:\\\\Temp\\\\AXBD_Cleaned.bacpac\\\"\\nThis will remove the SqlView(s) \\\"dbo.View1\\\" and \\\"View2\\\" from inside the bacpac file.\\nIt uses \\\"C:\\\\Temp\\\\AxDB.bacpac\\\" as the Path for the bacpac file.\\r\\nIt uses \\\"dbo.View1\\\",\\\"View2\\\" as the names of objects to delete.\\r\\nIt uses \\\"C:\\\\Temp\\\\AXBD_Cleaned.bacpac\\\" as the OutputPath to where it will store the updated bacpac file.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eClear-D365BacpacObject -Path \\\"C:\\\\Temp\\\\AxDB.bacpac\\\" -ObjectType SqlIndex -Name \\\"[dbo].[SalesTable].[CustomIndexName1]\\\" -ClearFromSource\\nThis will remove the SqlIndex \\\"CustomIndexName1\\\" from the dbo.SalesTable table from inside the bacpac file.\\nIt uses \\\"C:\\\\Temp\\\\AxDB.bacpac\\\" as the Path for the bacpac file.\\r\\nIt uses \\\"[dbo].[SalesTable].[CustomIndexName1]\\\" as the name of the object to delete.\\nCaution:\\r\\nIt will remove from the source \\\"C:\\\\Temp\\\\AxDB.bacpac\\\" directly. So if the original file is important for further processing, please consider the risks carefully.\",\n        \"Syntax\":  \"Clear-D365BacpacObject -Path \\u003cString\\u003e -Name \\u003cString[]\\u003e [-ObjectType \\u003cString\\u003e] -OutputPath \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\\nClear-D365BacpacObject -Path \\u003cString\\u003e -Name \\u003cString[]\\u003e [-ObjectType \\u003cString\\u003e] -ClearFromSource [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Clear-D365BacpacTableData\",\n        \"Description\":  \"Remove all data for a table inside a bacpac/dacpac or zip file, before restoring it into your SQL Server / Azure SQL DB\\n\\nIt will open the file as a zip archive, locate the desired table and remove the data that otherwise would have been loaded\\n\\nThe default behavior is that you get a copy of the file, where the desired data is removed\",\n        \"Tags\":  [\n                     \"Bacpac\",\n                     \"Servicing\",\n                     \"Data\",\n                     \"Deletion\",\n                     \"SqlPackage\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the bacpac/dacpac or zip file that you want to work against\",\n                           \"BacpacFile,File\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Table\",\n                           \"Name of the table that you want to delete the data for\\nSupports an array of table names\\nIf a schema name isn\\u0027t supplied as part of the table name, the cmdlet will prefix it with \\\"dbo.\\\"\\nSupports wildcard searching e.g. \\\"Sales*\\\" will delete all \\\"dbo.Sales*\\\" tables in the bacpac file\",\n                           \"TableName\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the updated bacpac/dacpac or zip file to be saved\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ClearFromSource\",\n                           \"Instruct the cmdlet to delete tables directly from the source file\\nIt will save disk space and time, because it doesn\\u0027t have to create a copy of the bacpac file, before deleting tables from it\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"Clear-D365TableDataFromBacpac\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Clear out data for a table inside the bacpac/dacpac or zip file\",\n        \"Name\":  \"Clear-D365BacpacTableData\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eClear-D365BacpacTableData -Path \\\"C:\\\\Temp\\\\AxDB.bacpac\\\" -Table \\\"BATCHJOBHISTORY\\\" -OutputPath \\\"C:\\\\Temp\\\\AXBD_Cleaned.bacpac\\\"\\nThis will remove the data from the BatchJobHistory table from inside the bacpac file.\\nIt uses \\\"C:\\\\Temp\\\\AxDB.bacpac\\\" as the Path for the bacpac file.\\r\\nIt uses \\\"BATCHJOBHISTORY\\\" as the Table to delete data from.\\r\\nIt uses \\\"C:\\\\Temp\\\\AXBD_Cleaned.bacpac\\\" as the OutputPath to where it will store the updated bacpac file.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eClear-D365BacpacTableData -Path \\\"C:\\\\Temp\\\\AxDB.bacpac\\\" -Table \\\"dbo.BATCHHISTORY\\\",\\\"BATCHJOBHISTORY\\\" -OutputPath \\\"C:\\\\Temp\\\\AXBD_Cleaned.bacpac\\\"\\nThis will remove the data from the dbo.BatchHistory and BatchJobHistory table from inside the bacpac file.\\nIt uses \\\"C:\\\\Temp\\\\AxDB.bacpac\\\" as the Path for the bacpac file.\\r\\nIt uses \\\"dbo.BATCHHISTORY\\\",\\\"BATCHJOBHISTORY\\\" as the Table to delete data from.\\r\\nIt uses \\\"C:\\\\Temp\\\\AXBD_Cleaned.bacpac\\\" as the OutputPath to where it will store the updated bacpac file.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eClear-D365BacpacTableData -Path \\\"C:\\\\Temp\\\\AxDB.bacpac\\\" -Table \\\"dbo.BATCHHISTORY\\\",\\\"BATCHJOBHISTORY\\\" -ClearFromSource\\nThis will remove the data from the dbo.BatchHistory and BatchJobHistory table from inside the bacpac file.\\nIt uses \\\"C:\\\\Temp\\\\AxDB.bacpac\\\" as the Path for the bacpac file.\\r\\nIt uses \\\"dbo.BATCHHISTORY\\\",\\\"BATCHJOBHISTORY\\\" as the Table to delete data from.\\nCaution:\\r\\nIt will remove from the source \\\"C:\\\\Temp\\\\AxDB.bacpac\\\" directly. So if the original file is important for further processing, please consider the risks carefully.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eClear-D365BacpacTableData -Path \\\"C:\\\\Temp\\\\AxDB.bacpac\\\" -Table \\\"CustomTableNameThatDoesNotExists\\\",\\\"BATCHJOBHISTORY\\\" -OutputPath \\\"C:\\\\Temp\\\\AXBD_Cleaned.bacpac\\\" -ErrorAction SilentlyContinue\\nThis will remove the data from the BatchJobHistory table from inside the bacpac file.\\nIt uses \\\"C:\\\\Temp\\\\AxDB.bacpac\\\" as the Path for the bacpac file.\\r\\nIt uses \\\"CustomTableNameThatDoesNotExists\\\",\\\"BATCHJOBHISTORY\\\" as the Table to delete data from.\\r\\nIt respects the respects the ErrorAction \\\"SilentlyContinue\\\", and will continue removing tables from the bacpac file, even when some tables are missing.\\r\\nIt uses \\\"C:\\\\Temp\\\\AXBD_Cleaned.bacpac\\\" as the OutputPath to where it will store the updated bacpac file.\",\n        \"Syntax\":  \"Clear-D365BacpacTableData -Path \\u003cString\\u003e -Table \\u003cString[]\\u003e -OutputPath \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\\nClear-D365BacpacTableData -Path \\u003cString\\u003e -Table \\u003cString[]\\u003e -ClearFromSource [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Clear-D365MonitorData\",\n        \"Description\":  \"Clear the monitoring data that is filling up the service drive on a Dynamics 365 for Finance \\u0026 Operations\",\n        \"Tags\":  [\n                     \"Monitor\",\n                     \"MonitorData\",\n                     \"MonitorAgent\",\n                     \"CleanUp\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"The path to where the monitoring data is located\\nThe default value is the \\\"ServiceDrive\\\" (j:\\\\ | k:\\\\) and the \\\\MonAgentData\\\\SingleAgent\\\\Tables folder structure\",\n                           \"\",\n                           false,\n                           \"true (ByValue, ByPropertyName)\",\n                           \"(Join-Path $script:ServiceDrive \\\"\\\\MonAgentData\\\\SingleAgent\\\\Tables\\\")\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Clear the monitoring data from a Dynamics 365 for Finance \\u0026 Operations machine\",\n        \"Name\":  \"Clear-D365MonitorData\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eClear-D365MonitorData\\nThis will delete all the files that are located in the default path on the machine.\\r\\nSome files might be locked by a process, but the cmdlet will attemp to delete all files.\",\n        \"Syntax\":  \"Clear-D365MonitorData [[-Path] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Clear-D365TempDbTables\",\n        \"Description\":  \"This will cleanup X days of TempDB tables\\n\\nThe reason behind this process is that sp_updatestats takes significantly longer depending on the number of TempDB tables in the system\",\n        \"Params\":  [\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"Days\",\n                           \"Temp tables older than this Days input will be dropped\\nThe default value is 7 (days)\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"7\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Alex Kwitny (@AlexOnDAX)\",\n        \"Synopsis\":  \"Cleanup TempDB tables in Microsoft Dynamics 365 for Finance and Operations environment\",\n        \"Name\":  \"Clear-D365TempDbTables\",\n        \"Links\":  [\n                      \"https://msdyn365fo.wordpress.com/2019/12/18/cleanup-tempdb-tables-in-a-msdyn365fo-sandbox-environment/\",\n                      \"https://github.com/PaulHeisterkamp/d365fo.blog/blob/master/Tools/SQL/DropTempDBTables.sql\"\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eClear-D365TempDbTables -Days 7\\nThis will cleanup old tempdb tables.\\r\\nIt will use 7 as the Days parameter.\\nThe remaining parameters will use their default values, which are provided by the tools.\",\n        \"Syntax\":  \"Clear-D365TempDbTables [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [[-Days] \\u003cInt32\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"ConvertTo-D365Dacpac\",\n        \"Description\":  \"Convert bacpac file to dacpac\\n\\nIt will extract the origin.xml file from the file, and set the \\u003cContainsExportedData\\u003efalse\\u003c/ContainsExportedData\\u003e for the file to be valid to be used as a dacpac file\",\n        \"Tags\":  [\n                     \"Bacpac\",\n                     \"Servicing\",\n                     \"Data\",\n                     \"SqlPackage\",\n                     \"Dacpac\",\n                     \"Table\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the bacpac file that you want to work against\\nIt can also be a zip file\",\n                           \"BacpacFile,File\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Convert bacpac file to dacpac\",\n        \"Name\":  \"ConvertTo-D365Dacpac\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eConvertTo-D365Dacpac -Path \\\"C:\\\\Temp\\\\AxDB.bacpac\\\"\\nThis will convert the bacpac file into a dacpac file.\\r\\nIt will extract the origin.xml file, update it and apply it to the file.\\r\\nIt will rename the file into a dacpac.\\nThe source file will be manipulated, so be careful to have an extra copy of the file.\",\n        \"Syntax\":  \"ConvertTo-D365Dacpac [-Path] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Disable-D365Exception\",\n        \"Description\":  \"Restore the default exception behavior of the module to not support throwing exceptions\\n\\nUseful when the default behavior was changed with Enable-D365Exception and the default behavior should be restored\",\n        \"Tags\":  [\n                     \"Exception\",\n                     \"Exceptions\",\n                     \"Warning\",\n                     \"Warnings\"\n                 ],\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Florian Hopfner (@FH-Inway)\",\n        \"Synopsis\":  \"Disables throwing of exceptions\",\n        \"Name\":  \"Disable-D365Exception\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eDisable-D365Exception\\nThis will restore the default behavior of the module to not support throwing exceptions.\",\n        \"Syntax\":  \"Disable-D365Exception [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Disable-D365Flight\",\n        \"Description\":  \"Provides a method for disabling a flight in D365FO.\",\n        \"Tags\":  [\n                     \"Flight\",\n                     \"Flighting\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"FlightName\",\n                           \"Name of the flight to disable\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Frank Hüther (@FrankHuether)\",\n        \"Synopsis\":  \"Used to disable a flight\",\n        \"Name\":  \"Disable-D365Flight\",\n        \"Links\":  \"https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages#features-flighted-in-data-management-and-enabling-flighted-features\",\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eDisable-D365Flight -FlightName DMFEnableAllCompanyExport\\nDisables the flight DMFEnableAllCompanyExport\",\n        \"Syntax\":  \"Disable-D365Flight [-FlightName] \\u003cString\\u003e [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Disable-D365IISPreload\",\n        \"Description\":  \"Reverts IIS Preload settings for the AOSService application:\\n- Sets Application Pool Start Mode to OnDemand\\n- Sets Idle Time-out to 0 (default)\\n- Disables Preload on the AOSService website\\n- Sets doAppInitAfterRestart to false (if Application Initialization is installed)\\n- Restores previous IIS Preload configuration from backup if available\\n- Restores or removes the initializationPage property as appropriate\\n- Uninstalls IIS Application Initialization feature if it was not installed in the backup\",\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Florian Hopfner (FH-Inway)\",\n        \"Synopsis\":  \"Disables IIS Preload for the AOSService application pool and website.\",\n        \"Name\":  \"Disable-D365IISPreload\",\n        \"Links\":  [\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eDisable-D365IISPreload\\nDisables IIS Preload for the AOSService application pool and website, restoring previous settings from backup if available.\",\n        \"Syntax\":  \"Disable-D365IISPreload [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Disable-D365MaintenanceMode\",\n        \"Description\":  \"Sets the Dynamics 365 environment back into operating / running state after it has been in maintenance mode.\",\n        \"Tags\":  [\n                     \"MaintenanceMode\",\n                     \"Maintenance\",\n                     \"License\",\n                     \"Configuration\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"MetaDataDir\",\n                           \"The path to the meta data directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:MetaDataDir\\\"\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\"\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"The path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\MaintenanceMode\\\")\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable or SQL script and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@splaxi)\",\n        \"Synopsis\":  \"Sets the environment back into operating state\",\n        \"Name\":  \"Disable-D365MaintenanceMode\",\n        \"Links\":  [\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eDisable-D365MaintenanceMode\\nOn VHD based environments, this will execute the Microsoft.Dynamics.AX.Deployment.Setup.exe with the default values that was pulled from the environment and put the environment into the operate / \\r\\nrunning state. On cloud hosted environments, a SQL script is used instead.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eDisable-D365MaintenanceMode -ShowOriginalProgress\\nOn VHD based environments, this will execute the Microsoft.Dynamics.AX.Deployment.Setup.exe with the default values that was pulled from the environment and put the environment into the operate / \\r\\nrunning state. On cloud hosted environments, a SQL script is used instead.\\r\\nThe output from stopping the services will be written to the console / host.\\r\\nThe output from the \\\"deployment\\\" process will be written to the console / host.\\r\\nThe output from starting the services will be written to the console / host.\",\n        \"Syntax\":  \"Disable-D365MaintenanceMode [[-MetaDataDir] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [[-LogPath] \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Disable-D365SqlChangeTracking\",\n        \"Description\":  \"Disables the SQL Server Change Tracking for the environments database and all tables inside the database\",\n        \"Tags\":  [\n                     \"MaintenanceMode\",\n                     \"Maintenance\",\n                     \"License\",\n                     \"Configuration\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@splaxi)\",\n        \"Synopsis\":  \"Disable Change Tracking for the environment\",\n        \"Name\":  \"Disable-D365SqlChangeTracking\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eDisable-D365SqlChangeTracking\\nThis will disable the Change Tracking on the Sql Server.\",\n        \"Syntax\":  \"Disable-D365SqlChangeTracking [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Disable-D365User\",\n        \"Description\":  \"Sets the enabled to 0 in the userinfo table.\",\n        \"Tags\":  [\n                     \"User\",\n                     \"Users\",\n                     \"Security\",\n                     \"Configuration\",\n                     \"Permission\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"Email\",\n                           \"The search string to select which user(s) should be disabled.\\nThe parameter supports wildcards. E.g. -Email \\\"*@contoso.com*\\\"\",\n                           \"\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"*\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Disables the user in D365FO\",\n        \"Name\":  \"Disable-D365User\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eDisable-D365User\\nThis will Disable all users for the environment\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eDisable-D365User -Email \\\"claire@contoso.com\\\"\\nThis will Disable the user with the email address \\\"claire@contoso.com\\\"\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eDisable-D365User -Email \\\"*contoso.com\\\"\\nThis will Disable all users that matches the search \\\"*contoso.com\\\" in their email address\",\n        \"Syntax\":  \"Disable-D365User [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [[-Email] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Enable-D365Exception\",\n        \"Description\":  \"Change the default exception behavior of the module to support throwing exceptions\\n\\nUseful when the module is used in an automated fashion, like inside Azure DevOps pipelines and large PowerShell scripts\",\n        \"Tags\":  [\n                     \"Exception\",\n                     \"Exceptions\",\n                     \"Warning\",\n                     \"Warnings\"\n                 ],\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Enable exceptions to be thrown\",\n        \"Name\":  \"Enable-D365Exception\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eEnable-D365Exception\\nThis will for the rest of the current PowerShell session make sure that exceptions will be thrown.\",\n        \"Syntax\":  \"Enable-D365Exception [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Enable-D365Flight\",\n        \"Description\":  \"Provides a method for enabling a flight in D365FO.\",\n        \"Tags\":  [\n                     \"Flight\",\n                     \"Flighting\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"FlightName\",\n                           \"Name of the flight to enable\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Frank Hüther (@FrankHuether)\",\n        \"Synopsis\":  \"Used to enable a flight\",\n        \"Name\":  \"Enable-D365Flight\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eEnable-D365Flight -FlightName DMFEnableAllCompanyExport\\nEnables the flight DMFEnableAllCompanyExport\",\n        \"Syntax\":  \"Enable-D365Flight [-FlightName] \\u003cString\\u003e [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Enable-D365IISPreload\",\n        \"Description\":  \"Configures IIS to preload the AOSService application, improving startup time after X++ compile.\\n- Sets Application Pool Start Mode to AlwaysRunning\\n- Sets Idle Time-out to 0\\n- Enables Preload on the AOSService website\\n- Sets doAppInitAfterRestart to true (if Application Initialization is installed)\\n- Optionally sets the initializationPage to a custom base URL\",\n        \"Params\":  [\n                       [\n                           \"BaseUrl\",\n                           \"The base URL to use for the initializationPage setting in IIS Application Initialization.\\r\\nIf not provided, the function will attempt to determine the base URL automatically using Get-D365Url.\\r\\nExample: https://usnconeboxax1aos.cloud.onebox.dynamics.com\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Florian Hopfner (FH-Inway)\",\n        \"Synopsis\":  \"Enables IIS Preload for the AOSService application pool and website.\",\n        \"Name\":  \"Enable-D365IISPreload\",\n        \"Links\":  [\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eEnable-D365IISPreload\\nThis will enable IIS Preload and set the initializationPage using the automatically detected base URL.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eEnable-D365IISPreload -BaseUrl \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\"\\nThis will enable IIS Preload and set the initializationPage to https://usnconeboxax1aos.cloud.onebox.dynamics.com/?mi=DefaultDashboard\",\n        \"Syntax\":  \"Enable-D365IISPreload [[-BaseUrl] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Enable-D365MaintenanceMode\",\n        \"Description\":  \"Sets the Dynamics 365 environment into maintenance mode to enable the user to update the license configuration\",\n        \"Tags\":  [\n                     \"MaintenanceMode\",\n                     \"Maintenance\",\n                     \"License\",\n                     \"Configuration\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"MetaDataDir\",\n                           \"The path to the meta data directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:MetaDataDir\\\"\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\"\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"The path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\MaintenanceMode\\\")\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable or SQL script and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@splaxi)\",\n        \"Synopsis\":  \"Sets the environment into maintenance mode\",\n        \"Name\":  \"Enable-D365MaintenanceMode\",\n        \"Links\":  [\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eEnable-D365MaintenanceMode\\nOn VHD based environments, this will execute the Microsoft.Dynamics.AX.Deployment.Setup.exe with the default values that was pulled from the environment and put the environment into the maintenance \\r\\nmode. On cloud hosted environments, a SQL script is used instead.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eEnable-D365MaintenanceMode -ShowOriginalProgress\\nOn VHD based environments, this will execute the Microsoft.Dynamics.AX.Deployment.Setup.exe with the default values that was pulled from the environment and put the environment into the maintenance \\r\\nmode. On cloud hosted environments, a SQL script is used instead.\\r\\nThe output from stopping the services will be written to the console / host.\\r\\nThe output from the \\\"deployment\\\" process will be written to the console / host.\\r\\nThe output from starting the services will be written to the console / host.\",\n        \"Syntax\":  \"Enable-D365MaintenanceMode [[-MetaDataDir] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [[-LogPath] \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Enable-D365SqlChangeTracking\",\n        \"Description\":  \"Enable the SQL Server Change Tracking for the environments database\\n\\nIt is a requirement for the Data Entities refresh to be able to complete correctly\",\n        \"Tags\":  [\n                     \"MaintenanceMode\",\n                     \"Maintenance\",\n                     \"License\",\n                     \"Configuration\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@splaxi)\",\n        \"Synopsis\":  \"Enable Change Tracking for the environment\",\n        \"Name\":  \"Enable-D365SqlChangeTracking\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eEnable-D365SqlChangeTracking\\nThis will enable the Change Tracking on the Sql Server.\",\n        \"Syntax\":  \"Enable-D365SqlChangeTracking [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Enable-D365User\",\n        \"Description\":  \"Sets the enabled to 1 in the userinfo table\",\n        \"Tags\":  [\n                     \"User\",\n                     \"Users\",\n                     \"Security\",\n                     \"Configuration\",\n                     \"Permission\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"Email\",\n                           \"The search string to select which user(s) should be enabled\\nThe parameter supports wildcards. E.g. -Email \\\"*@contoso.com*\\\"\\nDefault value is \\\"*\\\" to update all users\",\n                           \"\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"*\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen\",\n        \"Synopsis\":  \"Enables the user in D365FO\",\n        \"Name\":  \"Enable-D365User\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eEnable-D365User\\nThis will enable all users for the environment\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eEnable-D365User -Email \\\"claire@contoso.com\\\"\\nThis will enable the user with the email address \\\"claire@contoso.com\\\"\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eEnable-D365User -Email \\\"*contoso.com\\\"\\nThis will enable all users that matches the search \\\"*contoso.com\\\" in their email address\",\n        \"Syntax\":  \"Enable-D365User [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [[-Email] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Export-D365BacpacModelFile\",\n        \"Description\":  \"Extract the \\\"model.xml\\\" file from inside the bacpac file\\n\\nThis can be used to update SQL Server options for how the SqlPackage.exe should import the bacpac file into your SQL Server / Azure SQL DB\",\n        \"Tags\":  [\n                     \"Bacpac\",\n                     \"Servicing\",\n                     \"Data\",\n                     \"SqlPackage\",\n                     \"Sql Server Options\",\n                     \"Collation\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the bacpac file that you want to work against\\nIt can also be a zip file\",\n                           \"BacpacFile,File\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the updated bacpac file to be saved\\nDefault value is: \\\"c:\\\\temp\\\\d365fo.tools\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Switch to instruct the cmdlet to overwrite the \\\"model.xml\\\" specified in the OutputPath\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"Get-D365ModelFileFromBacpac\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Extract the \\\"model.xml\\\" from the bacpac file\",\n        \"Name\":  \"Export-D365BacpacModelFile\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eExport-D365BacpacModelFile -Path \\\"c:\\\\Temp\\\\AxDB.bacpac\\\"\\nThis will extract the \\\"model.xml\\\" file from inside the bacpac file.\\nIt uses \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" as the Path for the bacpac file.\\r\\nIt uses the default value \\\"c:\\\\temp\\\\d365fo.tools\\\" as the OutputPath to where it will store the extracted \\\"bacpac.model.xml\\\" file.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eExport-D365BacpacModelFile -Path \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" -OutputPath \\\"c:\\\\Temp\\\\model.xml\\\" -Force\\nThis will extract the \\\"model.xml\\\" file from inside the bacpac file.\\nIt uses \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" as the Path for the bacpac file.\\r\\nIt uses \\\"c:\\\\Temp\\\\model.xml\\\" as the OutputPath to where it will store the extracted \\\"model.xml\\\" file.\\nIt will override the \\\"c:\\\\Temp\\\\model.xml\\\" if already present.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eExport-D365BacpacModelFile -Path \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" | Get-D365BacpacSqlOptions\\nThis will display all the SQL Server options configured in the bacpac file.\\r\\nFirst it will export the bacpac.model.xml from the \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" file, using the Export-D365BacpacModelFile function.\\r\\nThe output from Export-D365BacpacModelFile will be piped into the Get-D365BacpacSqlOptions function.\",\n        \"Syntax\":  \"Export-D365BacpacModelFile [-Path] \\u003cString\\u003e [[-OutputPath] \\u003cString\\u003e] [-Force] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Export-D365Model\",\n        \"Description\":  \"Export a model from a Dynamics 365 for Finance \\u0026 Operations environment\",\n        \"Tags\":  [\n                     \"ModelUtil\",\n                     \"Axmodel\",\n                     \"Model\",\n                     \"Export\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the folder where you want to save the model file\",\n                           \"File\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Model\",\n                           \"Name of the model that you want to work against\",\n                           \"Modelname\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Instruct the cmdlet to overwrite already existing file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the AOS service PackagesLocalDirectory\\\\bin\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:PackageDirectory\\\\bin\\\"\"\n                       ],\n                       [\n                           \"MetaDataDir\",\n                           \"The path to the meta data directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:MetaDataDir\\\"\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"The path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\ModelUtilExport\\\")\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Export a model from Dynamics 365 for Finance \\u0026 Operations\",\n        \"Name\":  \"Export-D365Model\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eExport-D365Model -Path c:\\\\temp\\\\d365fo.tools -Model CustomModelName\\nThis will export the \\\"CustomModelName\\\" model from the default PackagesLocalDirectory path.\\r\\nIt export the model to the \\\"c:\\\\temp\\\\d365fo.tools\\\" location.\",\n        \"Syntax\":  \"Export-D365Model [-Path] \\u003cString\\u003e [-Model] \\u003cString\\u003e [-Force] [[-BinDir] \\u003cString\\u003e] [[-MetaDataDir] \\u003cString\\u003e] [[-LogPath] \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Export-D365SecurityDetails\",\n        \"Description\":  \"Extracts and partitions the security details from an User Interface Security file into the same structure as AOT security files\",\n        \"Tags\":  [\n                     \"Security\",\n                     \"Configuration\",\n                     \"Permission\",\n                     \"Development\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"FilePath\",\n                           \"Path to the User Interface Security XML file you want to work against\",\n                           \"Path\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"OutputDirectory\",\n                           \"Path to the folder where the cmdlet will output and structure the details from the file.\\r\\nThe cmdlet will create a sub folder named like the input file.\\nDefault value is: \\\"C:\\\\temp\\\\d365fo.tools\\\\security-extraction\\\"\",\n                           \"Output\",\n                           false,\n                           \"false\",\n                           \"C:\\\\temp\\\\d365fo.tools\\\\security-extraction\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@splaxi)\",\n        \"Synopsis\":  \"Extract details from a User Interface Security file\",\n        \"Name\":  \"Export-D365SecurityDetails\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eExport-D365SecurityDetails -FilePath C:\\\\temp\\\\d365fo.tools\\\\SecurityDatabaseCustomizations.xml\\nThis will grab all the details inside the \\\"C:\\\\temp\\\\d365fo.tools\\\\SecurityDatabaseCustomizations.xml\\\" file and extract that into the default path \\\"C:\\\\temp\\\\d365fo.tools\\\\security-extraction\\\"\",\n        \"Syntax\":  \"Export-D365SecurityDetails [-FilePath] \\u003cString\\u003e [[-OutputDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Find-D365Command\",\n        \"Description\":  \"Finds d365fo.tools commands searching through the inline help text, building a consolidated json index and querying it because Get-Help is too slow\",\n        \"Tags\":  [\n                     \"Find\",\n                     \"Help\",\n                     \"Command\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Pattern\",\n                           \"Searches help for all commands in d365fo.tools for the specified pattern and displays all results\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Tag\",\n                           \"Finds all commands tagged with this auto-populated tag\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Author\",\n                           \"Finds all commands tagged with this author\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"MinimumVersion\",\n                           \"Finds all commands tagged with this auto-populated minimum version\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"MaximumVersion\",\n                           \"Finds all commands tagged with this auto-populated maximum version\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Rebuild\",\n                           \"Rebuilds the index\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message.\\r\\nThis avoids overwhelming you with \\\"sea of red\\\" exceptions, but is inconvenient because it basically disables advanced scripting.\\r\\nUsing this switch turns this \\\"nice by default\\\" feature off and enables you to catch exceptions with your own try/catch.\",\n                           \"Silent\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"WhatIf\",\n                           \"Displays what would happen if the command is run\",\n                           \"wi\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Confirm\",\n                           \"Confirms overwrite of index\",\n                           \"cf\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Finds d365fo.tools commands searching through the inline help text\",\n        \"Name\":  \"Find-D365Command\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eFind-D365Command \\\"snapshot\\\"\\nFor lazy typers: finds all commands searching the entire help for \\\"snapshot\\\"\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eFind-D365Command -Pattern \\\"snapshot\\\"\\nFor rigorous typers: finds all commands searching the entire help for \\\"snapshot\\\"\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eFind-D365Command -Tag copy\\nFinds all commands tagged with \\\"copy\\\"\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eFind-D365Command -Tag copy,user\\nFinds all commands tagged with BOTH \\\"copy\\\" and \\\"user\\\"\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eFind-D365Command -Author Mötz\\nFinds every command whose author contains \\\"Mötz\\\"\\n-------------------------- EXAMPLE 6 --------------------------\\nPS C:\\\\\\u003eFind-D365Command -Author Mötz -Tag copy\\nFinds every command whose author contains \\\"Mötz\\\" and it tagged as \\\"copy\\\"\\n-------------------------- EXAMPLE 7 --------------------------\\nPS C:\\\\\\u003eFind-D365Command -Pattern snapshot -Rebuild\\nFinds all commands searching the entire help for \\\"snapshot\\\", rebuilding the index (good for developers)\",\n        \"Syntax\":  \"Find-D365Command [[-Pattern] \\u003cString\\u003e] [[-Tag] \\u003cString[]\\u003e] [[-Author] \\u003cString\\u003e] [[-MinimumVersion] \\u003cString\\u003e] [[-MaximumVersion] \\u003cString\\u003e] [-Rebuild] [-EnableException] [-WhatIf] [-Confirm] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365ActiveAzureStorageConfig\",\n        \"Description\":  \"Get active Azure Storage Account configuration object from the configuration store\",\n        \"Tags\":  [\n                     \"Azure\",\n                     \"Azure Storage\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"Token\",\n                     \"Blob\",\n                     \"Container\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputAsPsCustomObject\",\n                           \"Instruct the cmdlet to return a PsCustomObject object\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get active Azure Storage Account configuration\",\n        \"Name\":  \"Get-D365ActiveAzureStorageConfig\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365ActiveAzureStorageConfig\\nThis will get the active Azure Storage configuration.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365ActiveAzureStorageConfig -OutputAsPsCustomObject\\nThis will get the active Azure Storage configuration.\\r\\nThe object will be output as a PsCustomObject, for you to utilize across your scripts.\",\n        \"Syntax\":  \"Get-D365ActiveAzureStorageConfig [-OutputAsPsCustomObject] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365ActiveBroadcastMessageConfig\",\n        \"Description\":  \"Get active broadcast message configuration from the configuration store\",\n        \"Tags\":  [\n                     \"Servicing\",\n                     \"Message\",\n                     \"Users\",\n                     \"Environment\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"ClientId\",\n                     \"ClientSecret\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputAsHashtable\",\n                           \"Instruct the cmdlet to return a hastable object\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get active broadcast message configuration\",\n        \"Name\":  \"Get-D365ActiveBroadcastMessageConfig\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365ActiveBroadcastMessageConfig\\nThis will get the active broadcast message configuration.\",\n        \"Syntax\":  \"Get-D365ActiveBroadcastMessageConfig [-OutputAsHashtable] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365AOTObject\",\n        \"Description\":  \"Enables you to search for different AOT objects\",\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the package that you want to work against\",\n                           \"PackageDirectory\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"ObjectType\",\n                           \"The type of AOT object you\\u0027re searching for\",\n                           \"Type\",\n                           false,\n                           \"false\",\n                           \"@(\\\"AxClass\\\")\"\n                       ],\n                       [\n                           \"Name\",\n                           \"Name of the object that you\\u0027re looking for\\nAccepts wildcards for searching. E.g. -Name \\\"Work*status\\\"\\nDefault value is \\\"*\\\" which will search for all objects\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"SearchInPackages\",\n                           \"Switch to instruct the cmdlet to search in packages directly instead\\r\\nof searching in the XppMetaData directory under a given package\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"IncludePath\",\n                           \"Switch to instruct the cmdlet to include the path for the object found\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Search for AOT object\",\n        \"Name\":  \"Get-D365AOTObject\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365AOTObject -Name *flush* -ObjectType AxClass -Path \\\"C:\\\\AOSService\\\\PackagesLocalDirectory\\\\ApplicationFoundation\\\"\\nThis will search inside the ApplicationFoundation package for all AxClasses that matches the search *flush*.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365AOTObject -Name *flush* -ObjectType AxClass -IncludePath -Path \\\"C:\\\\AOSService\\\\PackagesLocalDirectory\\\\ApplicationFoundation\\\"\\nThis will search inside the ApplicationFoundation package for all AxClasses that matches the search *flush* and include the full path to the files.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365InstalledPackage -Name Application* | Get-D365AOTObject -Name *flush* -ObjectType AxClass\\nThis searches for all packages that matches Application* and pipes them into Get-D365AOTObject which will search for all AxClasses that matches the search *flush*.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365AOTObject -Path \\\"C:\\\\AOSService\\\\PackagesLocalDirectory\\\\*\\\" -Name *flush* -ObjectType AxClass -SearchInPackages\\nThis is an advanced example and shouldn\\u0027t be something you resolve to every time.\\nThis will search across all packages and will look for the all AxClasses that matches the search *flush*.\\r\\nIt will NOT search in the XppMetaData directory for each package.\\nThis can stress your system.\",\n        \"Syntax\":  \"Get-D365AOTObject [-Path] \\u003cString\\u003e [[-ObjectType] \\u003cString[]\\u003e] [[-Name] \\u003cString\\u003e] [-SearchInPackages] [-IncludePath] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365AzureDevOpsNuget\",\n        \"Description\":  \"Get Azure DevOps nugets from a feed, to list all available details\",\n        \"Params\":  [\n                       [\n                           \"Url\",\n                           \"The Azure DevOps url that you want to work against\\nIt needs to be the full url for the organization and project, e.g. \\\"https://dev.azure.com/Contoso/Financials\\\" - where Contoso is the organization and the Financials is the project.\",\n                           \"Uri\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"FeedName\",\n                           \"Name of the feed that you want to work against\\nThe feed name is found under the Artifacts area in Azure DevOps\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"PeronalAccessToken\",\n                           \"The Personal Access Token that you need to provide for the cmdlet to be able to communicate with the Azure DevOps REST services\\nThe Personal Access Token is configured via the Azure DevOps portal, on your own account\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Name\",\n                           \"Name of the package / nuget that you are searching for\\nSupports wildcard searching e.g. \\\"*platform*\\\" will output all packages / nugets that matches the search pattern\\nDefault value is \\\"*\\\" which will search for all packages / nugets\",\n                           \"PackageName\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"Latest\",\n                           \"Instruct the cmdlet to only fetch the latest package / nuget based on the version (highest)\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get Azure DevOps nugets\",\n        \"Name\":  \"Get-D365AzureDevOpsNuget\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365AzureDevOpsNuget -Uri \\\"https://dev.azure.com/Contoso/Financials\\\" -FeedName \\\"AASBuild365\\\" -PeronalAccessToken \\\"m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny\\\"\\nThis will list all packages / nugets from the Azure DevOps feed. Foreach packacge, it will list all available versions.\\r\\nThe http request will be going to the Uri \\\"https://dev.azure.com/Contoso/Financials\\\".\\r\\nThe feed is identified by the FeedName \\\"AASBuild365\\\".\\r\\nThe request will authenticate with the PeronalAccessToken \\\"m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny\\\"\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365AzureDevOpsNuget -Uri \\\"https://dev.azure.com/Contoso/Financials\\\" -FeedName \\\"AASBuild365\\\" -PeronalAccessToken \\\"m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny\\\" -Latest\\nThis will list all packages / nugets from the Azure DevOps feed. Foreach packacge, it will only list the latest version (highest).\\r\\nThe http request will be going to the Uri \\\"https://dev.azure.com/Contoso/Financials\\\".\\r\\nThe feed is identified by the FeedName \\\"AASBuild365\\\".\\r\\nThe request will authenticate with the PeronalAccessToken \\\"m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny\\\"\\r\\nThe cmdlet will only output the latest version by the Latest switch.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003e$currentNugets = Get-D365AzureDevOpsNuget -Uri \\\"https://dev.azure.com/Contoso/Financials\\\" -FeedName \\\"AASBuild365\\\" -PeronalAccessToken \\\"m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny\\\" \\r\\n-Latest\\nPS C:\\\\\\u003e foreach ($item in $currentNugets) {\\r\\nPS C:\\\\\\u003e     $lcsNugets = Get-D365LcsAssetFile -FileType NuGetPackage -AssetFilename \\\"$($item.Name)*\\\"\\r\\nPS C:\\\\\\u003e     foreach ($itemInner in $lcsNugets) {\\r\\nPS C:\\\\\\u003e         if ($itemInner.FileName -Match \\\"\\\\d+\\\\.\\\\d+\\\\.\\\\d+\\\\.\\\\d+\\\") {\\r\\nPS C:\\\\\\u003e             if ($([Version]$Matches[0]) -gt [Version]$item.Version) {\\r\\nPS C:\\\\\\u003e                 $itemInner\\r\\nPS C:\\\\\\u003e             }\\r\\nPS C:\\\\\\u003e         }\\r\\nPS C:\\\\\\u003e     }\\r\\nPS C:\\\\\\u003e }\\nThis will fetch all latest nugets from the Azure DevOps artifacts feed (nuget).\\r\\nFor each nuget found, it will fetch matching nugets from the LCS Asset Library and return those that have a higher version.\\nThis can be used to automatically download and push the latest nuget from LCS to Azure DevOps.\\r\\nNeeds to be put into work with Invoke-D365AzureDevOpsNugetPush\",\n        \"Syntax\":  \"Get-D365AzureDevOpsNuget [-Url] \\u003cString\\u003e [-FeedName] \\u003cString\\u003e [-PeronalAccessToken] \\u003cString\\u003e [[-Name] \\u003cString\\u003e] [-Latest] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365AzureStorageConfig\",\n        \"Description\":  \"Get all Azure Storage Account configuration objects from the configuration store\",\n        \"Tags\":  [\n                     \"Azure\",\n                     \"Azure Storage\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"Token\",\n                     \"Blob\",\n                     \"Container\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"The name of the Azure Storage Account you are looking for\\nDefault value is \\\"*\\\" to display all Azure Storage Account configs\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"OutputAsHashtable\",\n                           \"Instruct the cmdlet to return a hastable object\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get Azure Storage Account configs\",\n        \"Name\":  \"Get-D365AzureStorageConfig\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365AzureStorageConfig\\nThis will show all Azure Storage Account configs\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365AzureStorageConfig -OutputAsHashtable\\nThis will show all Azure Storage Account configs.\\r\\nEvery object will be output as a hashtable, for you to utilize as parameters for other cmdlets.\",\n        \"Syntax\":  \"Get-D365AzureStorageConfig [[-Name] \\u003cString\\u003e] [-OutputAsHashtable] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365AzureStorageFile\",\n        \"Description\":  \"Get information for files from an Azure Storage Account\",\n        \"Tags\":  [\n                     \"Azure\",\n                     \"Azure Storage\",\n                     \"Token\",\n                     \"Blob\",\n                     \"File\",\n                     \"Container\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"AccountId\",\n                           \"Storage Account Name / Storage Account Id where file information should be retrieved from\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:AzureStorageAccountId\"\n                       ],\n                       [\n                           \"AccessToken\",\n                           \"The token that has the needed permissions for the search action\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:AzureStorageAccessToken\"\n                       ],\n                       [\n                           \"SAS\",\n                           \"The SAS key for the storage account or blob container\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:AzureStorageSAS\"\n                       ],\n                       [\n                           \"Container\",\n                           \"Name of the blob container inside the storage account where file information should be retrieved from\",\n                           \"Blobname,Blob\",\n                           false,\n                           \"false\",\n                           \"$Script:AzureStorageContainer\"\n                       ],\n                       [\n                           \"Name\",\n                           \"Name of the files information should be retrieved for\\nAccepts wildcards for searching. E.g. -Name \\\"Application*Adaptor\\\"\\nDefault value is \\\"*\\\" which will search for all files\",\n                           \"FileName\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"Latest\",\n                           \"Instruct the cmdlet to only fetch the information of the latest file from the Azure Storage Account\",\n                           \"GetLatest\",\n                           true,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get file information from Azure Storage\",\n        \"Name\":  \"Get-D365AzureStorageFile\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365AzureStorageFile -AccountId \\\"miscfiles\\\" -AccessToken \\\"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\\\" -Container \\\"backupfiles\\\"\\nThis will get information for all files in the blob container \\\"backupfiles\\\".\\r\\nIt will use the AccessToken \\\"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\\\" to gain access.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365AzureStorageFile -AccountId \\\"miscfiles\\\" -AccessToken \\\"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\\\" -Container \\\"backupfiles\\\" -Latest\\nThis will get information for the latest (newest) file from the blob container \\\"backupfiles\\\".\\r\\nIt will use the AccessToken \\\"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\\\" to gain access to the container.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365AzureStorageFile -AccountId \\\"miscfiles\\\" -AccessToken \\\"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\\\" -Container \\\"backupfiles\\\" -Name \\\"*UAT*\\\"\\nThis will get information for all files in the blob container \\\"backupfiles\\\" that fits the \\\"*UAT*\\\" search value.\\r\\nIt will use the AccessToken \\\"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\\\" to gain access to the container.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365AzureStorageFile -AccountId \\\"miscfiles\\\" -SAS \\\"sv2018-03-28\\u0026siunlisted\\u0026src\\u0026sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\\\" -Container \\\"backupfiles\\\" -Latest\\nThis will get information for the latest (newest) file from the blob container \\\"backupfiles\\\".\\r\\nIt will use the SAS key \\\"sv2018-03-28\\u0026siunlisted\\u0026src\\u0026sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\\\" to gain access to the container.\",\n        \"Syntax\":  \"Get-D365AzureStorageFile [-AccountId \\u003cString\\u003e] [-AccessToken \\u003cString\\u003e] [-SAS \\u003cString\\u003e] [-Container \\u003cString\\u003e] [-Name \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\\nGet-D365AzureStorageFile [-AccountId \\u003cString\\u003e] [-AccessToken \\u003cString\\u003e] [-SAS \\u003cString\\u003e] [-Container \\u003cString\\u003e] -Latest [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365AzureStorageUrl\",\n        \"Description\":  \"Get a valid blob container url from an Azure Storage Account\",\n        \"Tags\":  [\n                     \"Azure\",\n                     \"Azure Storage\",\n                     \"Token\",\n                     \"Blob\",\n                     \"File\",\n                     \"Container\",\n                     \"LCS\",\n                     \"Asset\",\n                     \"Bacpac\",\n                     \"Backup\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"AccountId\",\n                           \"Storage Account Name / Storage Account Id you want to work against\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:AzureStorageAccountId\"\n                       ],\n                       [\n                           \"SAS\",\n                           \"The SAS key that you have created for the storage account or blob container\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:AzureStorageSAS\"\n                       ],\n                       [\n                           \"Container\",\n                           \"Name of the blob container inside the storage account you want to work against\",\n                           \"Blobname,Blob\",\n                           false,\n                           \"false\",\n                           \"$Script:AzureStorageContainer\"\n                       ],\n                       [\n                           \"OutputAsHashtable\",\n                           \"Instruct the cmdlet to return a hastable object\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get a blob Url from Azure Storage account\",\n        \"Name\":  \"Get-D365AzureStorageUrl\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365AzureStorageUrl -AccountId \\\"miscfiles\\\" -SAS \\\"sv2018-03-28\\u0026siunlisted\\u0026src\\u0026sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\\\" -Container \\\"backupfiles\\\"\\nThis will generate a valid Url for the blob container in the Azure Storage Account.\\r\\nIt will use the AccountId \\\"miscfiles\\\" as the name of the storage account.\\r\\nIt will use the SAS key \\\"sv2018-03-28\\u0026siunlisted\\u0026src\\u0026sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\\\" to add the SAS token/key to the Url.\\r\\nIt will use the Container \\\"backupfiles\\\" as the container name in the Url.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365AzureStorageUrl\\nThis will generate a valid Url for the blob container in the Azure Storage Account.\\r\\nIt will use the default values that are configured using the Set-D365ActiveAzureStorageConfig cmdlet and view using the Get-D365ActiveAzureStorageConfig cmdlet.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365AzureStorageUrl -OutputAsHashtable\\nThis will generate a valid Url for the blob container in the Azure Storage Account.\\r\\nIt will use the default values that are configured using the Set-D365ActiveAzureStorageConfig cmdlet and view using the Get-D365ActiveAzureStorageConfig cmdlet.\\nThe output object will be a Hashtable, which you can use as a parameter for other cmdlets.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003e$DestinationParms = Get-D365AzureStorageUrl -OutputAsHashtable\\nPS C:\\\\\\u003e $BlobFileDetails = Get-D365LcsDatabaseBackups -Latest | Invoke-D365AzCopyTransfer @DestinationParms\\r\\nPS C:\\\\\\u003e $BlobFileDetails | Invoke-D365AzCopyTransfer -DestinationUri \\\"C:\\\\Temp\\\" -DeleteOnTransferComplete\\nThis will transfer the lastest backup file from LCS Asset Library to your local \\\"C:\\\\Temp\\\".\\r\\nIt will get a destination Url, for it to transfer the backup file between the LCS storage account and your own.\\r\\nThe newly transfered file, that lives in your own storage account, will then be downloaded to your local \\\"c:\\\\Temp\\\".\\nAfter the file has been downloaded to your local \\\"C:\\\\Temp\\\", it will be deleted from your own storage account.\",\n        \"Syntax\":  \"Get-D365AzureStorageUrl [[-AccountId] \\u003cString\\u003e] [[-SAS] \\u003cString\\u003e] [[-Container] \\u003cString\\u003e] [-OutputAsHashtable] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365BacpacSqlOptions\",\n        \"Description\":  \"Extract the SQL Server options that are listed inside the model.xml file originating from a bacpac file\",\n        \"Tags\":  [\n                     \"Bacpac\",\n                     \"Servicing\",\n                     \"Data\",\n                     \"SqlPackage\",\n                     \"Sql Server Options\",\n                     \"Collation\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the extracted model.xml file that you want to work against\",\n                           \"File,ModelFile\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"Get-D365SqlOptionsFromBacpacModelFile\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the SQL Server options from the bacpac model.xml file\",\n        \"Name\":  \"Get-D365BacpacSqlOptions\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365BacpacSqlOptions -Path \\\"c:\\\\temp\\\\d365fo.tools\\\\bacpac.model.xml\\\"\\nThis will display all the SQL Server options configured in the bacpac model file.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eExport-D365BacpacModelFile -Path \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" | Get-D365BacpacSqlOptions\\nThis will display all the SQL Server options configured in the bacpac file.\\r\\nFirst it will export the model.xml from the \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" file, using the Export-D365BacpacModelFile function.\\r\\nThe output from Export-D365BacpacModelFile will be piped into the Get-D365BacpacSqlOptions function.\",\n        \"Syntax\":  \"Get-D365BacpacSqlOptions [[-Path] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365BacpacTable\",\n        \"Description\":  \"Get tables and their metadata from the bacpac file\\n\\nMetadata as in original size and compressed size, which are what size the bulk files are and will only indicate what you can expect of the table size\",\n        \"Tags\":  [\n                     \"Bacpac\",\n                     \"Servicing\",\n                     \"Data\",\n                     \"SqlPackage\",\n                     \"Table\",\n                     \"Size\",\n                     \"Troubleshooting\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the bacpac file that you want to work against\\nIt can also be a zip file\",\n                           \"BacpacFile,File\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Table\",\n                           \"Name of the table that you want to delete the data for\\nSupports an array of table names\\nIf a schema name isn\\u0027t supplied as part of the table name, the cmdlet will prefix it with \\\"dbo.\\\"\\nSupports wildcard searching e.g. \\\"Sales*\\\" will locate all \\\"dbo.Sales*\\\" tables in the bacpac file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"Top\",\n                           \"Instruct the cmdlet with how many tables you want returned\\nDefault is [int]::max, which translates into all tables present inside the bapcac file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"2147483647\"\n                       ],\n                       [\n                           \"SortSizeAsc\",\n                           \"Instruct the cmdlet to sort the output by size (original) ascending\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"SortSizeDesc\",\n                           \"Instruct the cmdlet to sort the output by size (original) descending\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get tables from the bacpac file\",\n        \"Name\":  \"Get-D365BacpacTable\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365BacpacTable -Path \\\"c:\\\\Temp\\\\AxDB.bacpac\\\"\\nThis will return all tables from inside the bacpac file.\\nIt uses \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" as the Path for the bacpac file.\\r\\nIt uses the default value \\\"*\\\" as the Table parameter, to output all tables.\\r\\nIt uses the default value \\\"[int]::max\\\" as the Top parameter, to output all tables.\\r\\nIt uses the default sort, which is by name acsending.\\nA result set example:\\nName                                                                   OriginalSize CompressedSize BulkFiles\\r\\n----                                                                   ------------ -------------- ---------\\r\\nax.DBVERSION                                                                   62 B           52 B         1\\r\\ncrt.RETAILUPGRADEHISTORY                                                   13,49 MB       13,41 MB         3\\r\\ndbo.__AOSMESSAGEREGISTRATION                                                1,80 KB          540 B         2\\r\\ndbo.__AOSSTARTUPVERSION                                                         4 B            6 B         1\\r\\ndbo.ACCOUNTINGDISTRIBUTION                                                 48,60 MB        4,50 MB        95\\r\\ndbo.ACCOUNTINGEVENT                                                        11,16 MB        1,51 MB       128\\r\\ndbo.AGREEMENTPARAMETERS_RU                                                    366 B          113 B         1\\r\\ndbo.AIFSQLCDCENABLEDTABLES                                                 13,63 KB        2,19 KB         1\\r\\ndbo.AIFSQLCHANGETRACKINGENABLEDTABLES                                       9,89 KB        1,42 KB         1\\r\\ndbo.AIFSQLCTTRIGGERS                                                       44,75 KB        6,29 KB         1\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365BacpacTable -Path \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" -SortSizeAsc\\nThis will return all tables from inside the bacpac file, sorted by the original size, ascending.\\nIt uses \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" as the Path for the bacpac file.\\r\\nIt uses the default value \\\"*\\\" as the Table parameter, to output all tables.\\r\\nIt uses the default value \\\"[int]::max\\\" as the Top parameter, to output all tables.\\r\\nIt uses the SortSizeAsc parameter, which is by original size acsending.\\nA result set example:\\nName                                                                   OriginalSize CompressedSize BulkFiles\\r\\n----                                                                   ------------ -------------- ---------\\r\\ndbo.__AOSSTARTUPVERSION                                                         4 B            6 B         1\\r\\ndbo.SYSSORTORDER                                                               20 B           20 B         1\\r\\ndbo.SECURITYDATABASESETTINGS                                                   20 B           12 B         1\\r\\ndbo.SYSPOLICYSEQUENCEGROUP                                                     24 B           10 B         1\\r\\ndbo.SYSFILESTOREPARAMETERS                                                     26 B           10 B         1\\r\\ndbo.SYSHELPCPSSETUP                                                            28 B           15 B         1\\r\\ndbo.DATABASELOGPARAMETERS                                                      28 B           10 B         1\\r\\ndbo.FEATUREMANAGEMENTPARAMETERS                                                28 B           10 B         1\\r\\ndbo.AIFSQLCTVERSION                                                            28 B           24 B         1\\r\\ndbo.SYSHELPSETUP                                                               28 B           15 B         1\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365BacpacTable -Path \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" -SortSizeDesc\\nThis will return all tables from inside the bacpac file, sorted by the original size, descending.\\nIt uses \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" as the Path for the bacpac file.\\r\\nIt uses the default value \\\"*\\\" as the Table parameter, to output all tables.\\r\\nIt uses the default value \\\"[int]::max\\\" as the Top parameter, to output all tables.\\r\\nIt uses the SortSizeDesc parameter, which is by original size descending.\\nA result set example:\\nName                                                                   OriginalSize CompressedSize BulkFiles\\r\\n----                                                                   ------------ -------------- ---------\\r\\ndbo.TSTIMESHEETLINESTAGING                                                 35,31 GB        2,44 GB      9077\\r\\ndbo.RESROLLUP                                                              13,30 GB      367,19 MB      3450\\r\\ndbo.PROJECTSTAGING                                                         11,31 GB      508,70 MB      2929\\r\\ndbo.TSTIMESHEETTABLESTAGING                                                 5,93 GB      246,65 MB      1564\\r\\ndbo.BATCHHISTORY                                                            5,80 GB      234,99 MB      1529\\r\\ndbo.HCMPOSITIONHIERARCHYSTAGING                                             5,16 GB      222,18 MB      1358\\r\\ndbo.ERLCSFILEASSETTABLE                                                     3,15 GB      217,68 MB       302\\r\\ndbo.EVENTINBOX                                                              2,92 GB      105,63 MB       747\\r\\ndbo.HCMPOSITIONV2STAGING                                                    2,79 GB      200,27 MB       755\\r\\ndbo.HCMEMPLOYEESTAGING                                                      2,49 GB      218,69 MB       677\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365BacpacTable -Path \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" -SortSizeDesc -Top 5\\nThis will return all tables from inside the bacpac file, sorted by the original size, descending.\\nIt uses \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" as the Path for the bacpac file.\\r\\nIt uses the default value \\\"*\\\" as the Table parameter, to output all tables.\\r\\nIt uses the value 5 as the Top parameter, to output only 5 tables, based on the sorting selected.\\r\\nIt uses the SortSizeDesc parameter, which is by original size descending.\\nA result set example:\\nName                                                                   OriginalSize CompressedSize BulkFiles\\r\\n----                                                                   ------------ -------------- ---------\\r\\ndbo.TSTIMESHEETLINESTAGING                                                 35,31 GB        2,44 GB      9077\\r\\ndbo.RESROLLUP                                                              13,30 GB      367,19 MB      3450\\r\\ndbo.PROJECTSTAGING                                                         11,31 GB      508,70 MB      2929\\r\\ndbo.TSTIMESHEETTABLESTAGING                                                 5,93 GB      246,65 MB      1564\\r\\ndbo.BATCHHISTORY                                                            5,80 GB      234,99 MB      1529\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eGet-D365BacpacTable -Path \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" -Table \\\"Sales*\\\"\\nThis will return all tables which matches the \\\"Sales*\\\" wildcard search from inside the bacpac file.\\nIt uses \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" as the Path for the bacpac file.\\r\\nIt uses the default value \\\"Sales*\\\" as the Table parameter, to output all tables that matches the wildcard pattern.\\r\\nIt uses the default value \\\"[int]::max\\\" as the Top parameter, to output all tables.\\r\\nIt uses the default sort, which is by name acsending.\\nA result set example:\\nName                                                                   OriginalSize CompressedSize BulkFiles\\r\\n----                                                                   ------------ -------------- ---------\\r\\ndbo.SALESPARAMETERS                                                         4,29 KB          310 B         1\\r\\ndbo.SALESPARMUPDATE                                                       273,48 KB       24,21 KB         1\\r\\ndbo.SALESQUOTATIONTOLINEPARAMETERS                                          4,18 KB          596 B         1\\r\\ndbo.SALESSUMMARYPARAMETERS                                                  2,95 KB          425 B         1\\r\\ndbo.SALESTABLE                                                              1,20 KB          313 B         1\\r\\ndbo.SALESTABLE_W                                                              224 B           60 B         1\\r\\ndbo.SALESTABLE2LINEPARAMETERS                                               4,46 KB          637 B         1\\n-------------------------- EXAMPLE 6 --------------------------\\nPS C:\\\\\\u003eGet-D365BacpacTable -Path \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" -Table \\\"Sales*\\\",\\\"CUSTINVOICE*\\\"\\nThis will return all tables which matches the \\\"Sales*\\\" and \\\"CUSTINVOICE*\\\" wildcard searches from inside the bacpac file.\\nIt uses \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" as the Path for the bacpac file.\\r\\nIt uses the default value \\\"Sales*\\\" and \\\"CUSTINVOICE*\\\" as the Table parameter, to output all tables that matches the wildcard pattern.\\r\\nIt uses the default value \\\"[int]::max\\\" as the Top parameter, to output all tables.\\r\\nIt uses the default sort, which is by name acsending.\\nA result set example:\\nName                                                                   OriginalSize CompressedSize BulkFiles\\r\\n----                                                                   ------------ -------------- ---------\\r\\ndbo.CUSTINVOICEJOUR                                                         2,01 MB      118,87 KB         1\\r\\ndbo.CUSTINVOICELINE                                                        14,64 MB      975,30 KB         4\\r\\ndbo.CUSTINVOICELINEINTERPROJ                                                6,58 MB      477,97 KB         2\\r\\ndbo.CUSTINVOICETABLE                                                        1,06 MB       56,56 KB         1\\r\\ndbo.CUSTINVOICETRANS                                                       32,34 MB        1,51 MB        54\\r\\ndbo.SALESPARAMETERS                                                         4,29 KB          310 B         1\\r\\ndbo.SALESPARMUPDATE                                                       273,48 KB       24,21 KB         1\\r\\ndbo.SALESQUOTATIONTOLINEPARAMETERS                                          4,18 KB          596 B         1\\r\\ndbo.SALESSUMMARYPARAMETERS                                                  2,95 KB          425 B         1\\r\\ndbo.SALESTABLE                                                              1,20 KB          313 B         1\\r\\ndbo.SALESTABLE_W                                                              224 B           60 B         1\\r\\ndbo.SALESTABLE2LINEPARAMETERS                                               4,46 KB          637 B         1\\n-------------------------- EXAMPLE 7 --------------------------\\nPS C:\\\\\\u003eGet-D365BacpacTable -Path \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" -Table \\\"SalesTable\\\",\\\"CustTable\\\"\\nThis will return the tables \\\"dbo.SalesTable\\\" and \\\"dbo.CustTable\\\" from inside the bacpac file.\\nIt uses \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" as the Path for the bacpac file.\\r\\nIt uses the default value \\\"SalesTable\\\" and \\\"CustTable\\\" as the Table parameter, to output the tables that matches the names.\\r\\nIt uses the default value \\\"[int]::max\\\" as the Top parameter, to output all tables.\\r\\nIt uses the default sort, which is by name acsending.\\nA result set example:\\nName                                                                   OriginalSize CompressedSize BulkFiles\\r\\n----                                                                   ------------ -------------- ---------\\r\\ndbo.CUSTTABLE                                                             154,91 KB        8,26 KB         1\\r\\ndbo.SALESTABLE                                                              1,20 KB          313 B         1\",\n        \"Syntax\":  \"Get-D365BacpacTable -Path \\u003cString\\u003e [-Table \\u003cString[]\\u003e] [-Top \\u003cInt32\\u003e] [\\u003cCommonParameters\\u003e]\\nGet-D365BacpacTable -Path \\u003cString\\u003e [-Table \\u003cString[]\\u003e] [-Top \\u003cInt32\\u003e] [-SortSizeAsc] [\\u003cCommonParameters\\u003e]\\nGet-D365BacpacTable -Path \\u003cString\\u003e [-Table \\u003cString[]\\u003e] [-Top \\u003cInt32\\u003e] [-SortSizeDesc] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365BroadcastMessage\",\n        \"Description\":  \"Get broadcast message from the D365FO environment by looking into the database table\",\n        \"Tags\":  [\n                     \"Broadcast\",\n                     \"Message\",\n                     \"SysBroadcastMessage\",\n                     \"Servicing\",\n                     \"Message\",\n                     \"Users\",\n                     \"Environment\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"ExcludeExpired\",\n                           \"Exclude all the records that has already expired\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get broadcast message from the D365FO environment\",\n        \"Name\":  \"Get-D365BroadcastMessage\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365BroadcastMessage\\nThis will display all the broadcast message records from the SysBroadcastMessage table.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365BroadcastMessage -ExcludeExpired\\nThis will display all active the broadcast message records from the SysBroadcastMessage table.\",\n        \"Syntax\":  \"Get-D365BroadcastMessage [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [-ExcludeExpired] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365BroadcastMessageConfig\",\n        \"Description\":  \"Get all broadcast message configuration objects from the configuration store\",\n        \"Tags\":  [\n                     \"Servicing\",\n                     \"Message\",\n                     \"Users\",\n                     \"Environment\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"ClientId\",\n                     \"ClientSecret\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"The name of the broadcast message configuration you are looking for\\nDefault value is \\\"*\\\" to display all broadcast message configs\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"OutputAsHashtable\",\n                           \"Instruct the cmdlet to return a hastable object\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get broadcast message configs\",\n        \"Name\":  \"Get-D365BroadcastMessageConfig\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365BroadcastMessageConfig\\nThis will display all broadcast message configurations on the machine.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365BroadcastMessageConfig -OutputAsHashtable\\nThis will display all broadcast message configurations on the machine.\\r\\nEvery object will be output as a hashtable, for you to utilize as parameters for other cmdlets.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365BroadcastMessageConfig -Name \\\"UAT\\\"\\nThis will display the broadcast message configuration that is saved with the name \\\"UAT\\\" on the machine.\",\n        \"Syntax\":  \"Get-D365BroadcastMessageConfig [[-Name] \\u003cString\\u003e] [-OutputAsHashtable] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365ClickOnceTrustPrompt\",\n        \"Description\":  \"Creates the needed registry keys and values for ClickOnce to work on the machine\",\n        \"Tags\":  [\n                     \"ClickOnce\",\n                     \"Registry\",\n                     \"TrustPrompt\"\n                 ],\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the ClickOnce configuration\",\n        \"Name\":  \"Get-D365ClickOnceTrustPrompt\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365ClickOnceTrustPrompt\\nThis will get the current ClickOnce configuration\",\n        \"Syntax\":  \"Get-D365ClickOnceTrustPrompt [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365CompilerResult\",\n        \"Description\":  \"Get the compiler outputs presented in a structured manner on the screen\\n\\nIt could be a Visual Studio compiler log or it could be a Invoke-D365ModuleCompile log you want analyzed\",\n        \"Tags\":  [\n                     \"Compiler\",\n                     \"Build\",\n                     \"Errors\",\n                     \"Warnings\",\n                     \"Tasks\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the compiler log file that you want to work against\\nA BuildModelResult.log or a Dynamics.AX.*.xppc.log file will both work\",\n                           \"LogFile\",\n                           true,\n                           \"true (ByValue, ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"ErrorsOnly\",\n                           \"Instructs the cmdlet to only output compile results where there was errors detected\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputTotals\",\n                           \"Instructs the cmdlet to output the total errors and warnings after the analysis\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputAsObjects\",\n                           \"Instructs the cmdlet to output the objects instead of formatting them\\nIf you don\\u0027t assign the output, it will be formatted the same way as the original output, but without the coloring of the column values\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the compiler outputs presented\",\n        \"Name\":  \"Get-D365CompilerResult\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365CompilerResult -Path \\\"c:\\\\temp\\\\d365fo.tools\\\\Custom\\\\Dynamics.AX.Custom.xppc.log\\\"\\nThis will analyze the compiler log file for warning and errors.\\nA result set example:\\nFile                                                                                    Warnings Errors\\r\\n----                                                                                    -------- ------\\r\\nc:\\\\temp\\\\d365fo.tools\\\\Custom\\\\Dynamics.AX.Custom.xppc.log                                        2      1\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365CompilerResult -Path \\\"c:\\\\temp\\\\d365fo.tools\\\\Custom\\\\Dynamics.AX.Custom.xppc.log\\\" -ErrorsOnly\\nThis will analyze the compiler log file for warning and errors, but only output if it has errors.\\nA result set example:\\nFile                                                                                    Warnings Errors\\r\\n----                                                                                    -------- ------\\r\\nc:\\\\temp\\\\d365fo.tools\\\\Custom\\\\Dynamics.AX.Custom.xppc.log                                        2      1\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365CompilerResult -Path \\\"c:\\\\temp\\\\d365fo.tools\\\\Custom\\\\Dynamics.AX.Custom.xppc.log\\\" -ErrorsOnly -OutputAsObjects\\nThis will analyze the compiler log file for warning and errors, but only output if it has errors.\\r\\nThe output will be PSObjects, which can be assigned to a variable and used for futher analysis.\\nA result set example:\\nFile                                                                                    Warnings Errors\\r\\n----                                                                                    -------- ------\\r\\nc:\\\\temp\\\\d365fo.tools\\\\Custom\\\\Dynamics.AX.Custom.xppc.log                                        2      1\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365Module -Name *Custom* | Invoke-D365ModuleCompile | Get-D365CompilerResult -OutputTotals\\nThis will find all modules with Custom in their name.\\r\\nIt will pass thoses modules into the Invoke-D365ModuleCompile, which will compile them.\\r\\nIt will pass the paths to each compile output log to Get-D365CompilerResult, which will analyze them for warning and errors.\\r\\nIt will output the total number of warning and errors found.\\nFile                                                                                    Warnings Errors\\r\\n----                                                                                    -------- ------\\r\\nc:\\\\temp\\\\d365fo.tools\\\\Custom\\\\Dynamics.AX.Custom.xppc.log                                        2      1\\nTotal Errors: 1\\r\\nTotal Warnings: 2\",\n        \"Syntax\":  \"Get-D365CompilerResult [-Path] \\u003cString\\u003e [-ErrorsOnly] [-OutputTotals] [-OutputAsObjects] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365Database\",\n        \"Description\":  \"Get the names of databases on either SQL Server or in Azure SQL Database instance\",\n        \"Tags\":  [\n                     \"Database\",\n                     \"DB\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"Name of the database that you are looking for\\nDefault value is \\\"*\\\" which will show all databases\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get databases from the server\",\n        \"Name\":  \"Get-D365Database\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365Database\\nThis will show all databases on the default SQL Server / Azure SQL Database instance.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365Database -Name AXDB_ORIGINAL\\nThis will show if the AXDB_ORIGINAL database exists on the default SQL Server / Azure SQL Database instance.\",\n        \"Syntax\":  \"Get-D365Database [[-Name] \\u003cString[]\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365DatabaseAccess\",\n        \"Description\":  \"Gets all database information from the D365 environment\",\n        \"Tags\":  [\n                     \"Database\",\n                     \"Connection\",\n                     \"Sql\",\n                     \"SqlUser\",\n                     \"SqlPwd\"\n                 ],\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Rasmus Andersen (@ITRasmus)\",\n        \"Synopsis\":  \"Shows the Database Access information for the D365 Environment\",\n        \"Name\":  \"Get-D365DatabaseAccess\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365DatabaseAccess\\nThis will get all relevant details, including connection details, for the database configured for the environment\",\n        \"Syntax\":  \"Get-D365DatabaseAccess [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365DecryptedWebConfig\",\n        \"Description\":  \"Function used for decrypting the config file used by the D365 Finance \\u0026 Operations AOS service\",\n        \"Tags\":  [\n                     \"Configuration\",\n                     \"Service Account\",\n                     \"Sql\",\n                     \"SqlUser\",\n                     \"SqlPwd\",\n                     \"WebConfig\",\n                     \"Web.Config\",\n                     \"Decryption\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Place where the decrypted files should be placed\\nDefault value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\WebConfigDecrypted\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"c:\\\\temp\\\\d365fo.tools\\\\WebConfigDecrypted\"\n                       ],\n                       [\n                           \"AosServiceWebRootPath\",\n                           \"Location of the D365 webroot folder\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:AOSPath\"\n                       ]\n                   ],\n        \"Alias\":  \"Get-D365DecryptedConfigFile\",\n        \"Synopsis\":  \"Decrypts the AOS config file\",\n        \"Name\":  \"Get-D365DecryptedWebConfig\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365DecryptedWebConfig\\nThis will get the config file from the instance, decrypt it and save it.\\r\\nIT will save the decrypted web.config file in the default location: \\\"c:\\\\temp\\\\d365fo.tools\\\\WebConfigDecrypted\\\".\\nA result set example:\\nFilename   LastModified        File\\r\\n--------   ------------        ----\\r\\nweb.config 7/1/2021 9:01:31 PM C:\\\\temp\\\\d365fo.tools\\\\WebConfigDecrypted\\\\web.config\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365DecryptedWebConfig -OutputPath \\\"c:\\\\temp\\\\d365fo.tools\\\"\\nThis will get the config file from the instance, decrypt it and save it to \\\"c:\\\\temp\\\\d365fo.tools\\\"\\nA result set example:\\nFilename   LastModified        File\\r\\n--------   ------------        ----\\r\\nweb.config 7/1/2021 9:07:36 PM C:\\\\temp\\\\d365fo.tools\\\\web.config\",\n        \"Syntax\":  \"Get-D365DecryptedWebConfig [[-OutputPath] \\u003cString\\u003e] [[-AosServiceWebRootPath] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365DefaultModelForNewProjects\",\n        \"Description\":  \"Get the registered default model that is used across all new projects that are created inside Visual Studio when working with D365FO project types\",\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the default model used creating new projects in Visual Studio\",\n        \"Name\":  \"Get-D365DefaultModelForNewProjects\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365DefaultModelForNewProjects\\nThis will display the current default module registered in the \\\"DynamicsDevConfig.xml\\\" file.\\r\\nLocated in Documents\\\\Visual Studio Dynamics 365\\\\ or in Documents\\\\Visual Studio 2015\\\\Settings\\\\ depending on the version.\",\n        \"Syntax\":  \"Get-D365DefaultModelForNewProjects [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365DotNetClass\",\n        \"Description\":  \"Get a .NET class from an assembly file (dll) from the package directory\",\n        \"Tags\":  [\n                     \".Net\",\n                     \"DotNet\",\n                     \"Class\",\n                     \"Development\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"Name of the .NET class that you are looking for\\nAccepts wildcards for searching. E.g. -Name \\\"ER*Excel*\\\"\\nDefault value is \\\"*\\\" which will search for all classes\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"Assembly\",\n                           \"Name of the assembly file that you want to search for the .NET class\\nAccepts wildcards for searching. E.g. -Name \\\"*AX*Framework*.dll\\\"\\nDefault value is \\\"*.dll\\\" which will search for assembly files\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*.dll\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed packages\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get a .NET class from the Dynamics 365 for Finance and Operations installation\",\n        \"Name\":  \"Get-D365DotNetClass\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365DotNetClass -Name \\\"ERText*\\\"\\nWill search across all assembly files (*.dll) that are located in the default package directory after\\r\\nany class that fits the search \\\"ERText*\\\"\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365DotNetClass -Name \\\"ERText*\\\" -Assembly \\\"*LocalizationFrameworkForAx.dll*\\\"\\nWill search across all assembly files (*.dll) that are fits the search \\\"*LocalizationFrameworkForAx.dll*\\\",\\r\\nthat are located in the default package directory, after any class that fits the search \\\"ERText*\\\"\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365DotNetClass -Name \\\"ERText*\\\" | Export-Csv -Path c:\\\\temp\\\\results.txt -Delimiter \\\";\\\"\\nWill search across all assembly files (*.dll) that are located in the default package directory after\\r\\nany class that fits the search \\\"ERText*\\\"\\nThe output is saved to a file to make it easier to search inside the result set\",\n        \"Syntax\":  \"Get-D365DotNetClass [[-Name] \\u003cString\\u003e] [[-Assembly] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365DotNetMethod\",\n        \"Description\":  \"Get a .NET method from an assembly file (dll) from the package directory\",\n        \"Tags\":  [\n                     \".Net\",\n                     \"DotNet\",\n                     \"Class\",\n                     \"Method\",\n                     \"Methods\",\n                     \"Development\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Assembly\",\n                           \"Name of the assembly file that you want to search for the .NET method\\nProvide the full path for the assembly file you want to work against\",\n                           \"File\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"Name\",\n                           \"Name of the .NET method that you are looking for\\nAccepts wildcards for searching. E.g. -Name \\\"parmER*Excel*\\\"\\nDefault value is \\\"*\\\" which will search for all methods\",\n                           \"MethodName\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"TypeName\",\n                           \"Name of the .NET class that you want to work against\\nAccepts wildcards for searching. E.g. -Name \\\"*ER*Excel*\\\"\\nDefault value is \\\"*\\\" which will work against all classes\",\n                           \"ClassName\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get a .NET method from the Dynamics 365 for Finance and Operations installation\",\n        \"Name\":  \"Get-D365DotNetMethod\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365DotNetMethod -Assembly \\\"C:\\\\AOSService\\\\PackagesLocalDirectory\\\\ElectronicReporting\\\\bin\\\\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll\\\"\\nWill get all methods, across all classes, from the assembly file\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365DotNetMethod -Assembly \\\"C:\\\\AOSService\\\\PackagesLocalDirectory\\\\ElectronicReporting\\\\bin\\\\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll\\\" -TypeName \\\"ERTextFormatExcelFileComponent\\\"\\nWill get all methods, from the \\\"ERTextFormatExcelFileComponent\\\" class, from the assembly file\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365DotNetMethod -Assembly \\\"C:\\\\AOSService\\\\PackagesLocalDirectory\\\\ElectronicReporting\\\\bin\\\\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll\\\" -TypeName \\\"ERTextFormatExcelFileComponent\\\" \\r\\n-Name \\\"*parm*\\\"\\nWill get all methods that fits the search \\\"*parm*\\\", from the \\\"ERTextFormatExcelFileComponent\\\" class, from the assembly file\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365DotNetClass -Name \\\"ERTextFormatExcelFileComponent\\\" -Assembly \\\"*LocalizationFrameworkForAx.dll*\\\" | Get-D365DotNetMethod\\nWill get all methods, from the \\\"ERTextFormatExcelFileComponent\\\" class, from any assembly file that fits the search \\\"*LocalizationFrameworkForAx.dll*\\\"\",\n        \"Syntax\":  \"Get-D365DotNetMethod [-Assembly] \\u003cString\\u003e [[-Name] \\u003cString\\u003e] [[-TypeName] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365Environment\",\n        \"Description\":  \"List status for all relevant services that is running in a D365FO environment\",\n        \"Tags\":  [\n                     \"Environment\",\n                     \"Service\",\n                     \"Services\",\n                     \"Aos\",\n                     \"Batch\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"ComputerName\",\n                           \"An array of computers that you want to query for the services status on.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"@($env:computername)\"\n                       ],\n                       [\n                           \"All\",\n                           \"Set when you want to query all relevant services\\nIncludes:\\r\\nAos\\r\\nBatch\\r\\nFinancial Reporter\\r\\nDMF\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"True\"\n                       ],\n                       [\n                           \"Aos\",\n                           \"Instruct the cmdlet to query the AOS (IIS) service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Batch\",\n                           \"Instruct the cmdlet query the batch service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"FinancialReporter\",\n                           \"Instruct the cmdlet query the financial reporter (Management Reporter 2012)\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"DMF\",\n                           \"Instruct the cmdlet query the DMF service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OnlyStartTypeAutomatic\",\n                           \"Instruct the cmdlet to filter out services that are set to manual start or disabled\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputServiceDetailsOnly\",\n                           \"Instruct the cmdlet to exclude the server name from the output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Cmdlet to get the current status for the different services in a Dynamics 365 Finance \\u0026 Operations environment\",\n        \"Name\":  \"Get-D365Environment\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365Environment\\nWill query all D365FO service on the machine.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365Environment -All\\nWill query all D365FO service on the machine.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365Environment -OnlyStartTypeAutomatic\\nWill query all D365FO service on the machine.\\r\\nIt will filter out all services that are either configured as manual or disabled.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365Environment -ComputerName \\\"TEST-SB-AOS1\\\",\\\"TEST-SB-AOS2\\\",\\\"TEST-SB-BI1\\\" -All\\nWill query all D365FO service on the different machines.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eGet-D365Environment -Aos -Batch\\nWill query the Aos \\u0026 Batch services on the machine.\\n-------------------------- EXAMPLE 6 --------------------------\\nPS C:\\\\\\u003eGet-D365Environment -FinancialReporter -DMF\\nWill query the FinancialReporter \\u0026 DMF services on the machine.\\n-------------------------- EXAMPLE 7 --------------------------\\nPS C:\\\\\\u003eGet-D365Environment -OutputServiceDetailsOnly\\nWill query all D365FO service on the machine.\\r\\nWill omit the servername from the output.\\n-------------------------- EXAMPLE 8 --------------------------\\nPS C:\\\\\\u003eGet-D365Environment -FinancialReporter | Set-Service -StartupType Manual\\nThis will configure the Financial Reporter services to be start type manual.\",\n        \"Syntax\":  \"Get-D365Environment [[-ComputerName] \\u003cString[]\\u003e] [-All] [-OnlyStartTypeAutomatic] [-OutputServiceDetailsOnly] [\\u003cCommonParameters\\u003e]\\nGet-D365Environment [[-ComputerName] \\u003cString[]\\u003e] [-Aos] [-Batch] [-FinancialReporter] [-DMF] [-OnlyStartTypeAutomatic] [-OutputServiceDetailsOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365EnvironmentSettings\",\n        \"Description\":  \"Gets all settings the Dynamics 365 for Finance \\u0026 Operations environment uses.\",\n        \"Tags\":  [\n                     \"Environment\",\n                     \"Configuration\",\n                     \"WebConfig\",\n                     \"Web.Config\",\n                     \"Decryption\"\n                 ],\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Rasmus Andersen (@ITRasmus)\",\n        \"Synopsis\":  \"Get the D365FO environment settings\",\n        \"Name\":  \"Get-D365EnvironmentSettings\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365EnvironmentSettings\\nThis will get all details available for the environment\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365EnvironmentSettings | Format-Custom -Property *\\nThis will get all details available for the environment and format it to show all details in a long custom object.\",\n        \"Syntax\":  \"Get-D365EnvironmentSettings [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365EventTraceProvider\",\n        \"Description\":  \"Get the full list of available Event Trace Providers for Dynamics 365 for Finance and Operations\",\n        \"Tags\":  [\n                     \"ETL\",\n                     \"EventTracing\",\n                     \"EventTrace\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"Name of the provider that you are looking for\\nDefault value is \\\"*\\\" to show all Event Trace Providers\\nAccepts an array of names, and will automatically add wildcard searching characters for each entry\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"@(\\\"*\\\")\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get D365FO Event Trace Provider\",\n        \"Name\":  \"Get-D365EventTraceProvider\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365EventTraceProvider\\nWill list all available Event Trace Providers on a D365FO server.\\r\\nIt will use the default option for the \\\"Name\\\" parameter.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365EventTraceProvider -Name Tax\\nWill list all available Event Trace Providers on a D365FO server which contains the keyvword \\\"Tax\\\".\\r\\nIt will use the Name parameter value \\\"Tax\\\" while searching for Event Trace Providers.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365EventTraceProvider -Name Tax,MR\\nWill list all available Event Trace Providers on a D365FO server which contains the keyvword \\\"Tax\\\" or \\\"MR\\\".\\r\\nIt will use the Name parameter array value (\\\"Tax\\\",\\\"MR\\\") while searching for Event Trace Providers.\",\n        \"Syntax\":  \"Get-D365EventTraceProvider [[-Name] \\u003cString[]\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365ExternalIP\",\n        \"Description\":  \"Get the external IP address by calling an external webpage and interpret the result from that\",\n        \"Tags\":  [\n                     \"DEV\",\n                     \"Tier2\",\n                     \"DB\",\n                     \"Database\",\n                     \"Debug\",\n                     \"JIT\",\n                     \"LCS\",\n                     \"Azure DB\",\n                     \"IP\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"SaveToClipboard\",\n                           \"Instruct the cmdlet to copy the IP address directly into the clipboard, to save you the trouble\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the external IP address\",\n        \"Name\":  \"Get-D365ExternalIP\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365ExternalIP\\nWill call the external page, interpret the output and display it as output.\\nA result set example:\\nIpAddress\\r\\n---------\\r\\n40.113.130.229\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365ExternalIP -SaveToClipboard\\nWill call the external page, interpret the output and display it as output.\\r\\nIt will save/copy the IP address into the clipboard.\\nA result set example:\\nIpAddress\\r\\n---------\\r\\n40.113.130.229\",\n        \"Syntax\":  \"Get-D365ExternalIP [-SaveToClipboard] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365Flight\",\n        \"Description\":  \"Provides a method for listing a flight in D365FO.\",\n        \"Tags\":  [\n                     \"Flight\",\n                     \"Flighting\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"FlightName\",\n                           \"Name of the flight that you are looking for\\nSupports wildcards \\\"*\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Used to get a flight\",\n        \"Name\":  \"Get-D365Flight\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365Flight\\nThis will list all flights that are configured on the environment.\\r\\nIt will show the name and the enabled status.\\nA result set example:\\nFlightName                         Enabled FlightServiceId\\r\\n----------                         ------- ---------------\\r\\nWHSWorkCancelForcedFlight          1       12719367\\r\\nTAMRebateGlobalEnableFeature       1       12719367\\r\\nEnablePerfInfoSimpleLoggerV2       1       12719367\\r\\nEnablePerfInfoLogODataV2           1       12719367\\r\\nEnablePerfInfoLogEtwRequestTableV2 1       12719367\\r\\nEnablePerfInfoCursorLayerV2        1       12719367\\r\\nEnablePerfInfoFormEngineLayerV2    1       12719367\\r\\nEnablePerfInfoMutexWaitLayerV2     1       12719367\\r\\nEnablePerfInfoSecurityLayerV2      1       12719367\\r\\nEnablePerfInfoSessionLayerV2       1       12719367\\r\\nEnablePerfInfoSQLLayerV2           1       12719367\\r\\nEnablePerfInfoXppContainerLayerV2  1       12719367\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365Flight -FlightName WHSWorkCancelForcedFlight\\nThis will list the flight with the specified name on the environment.\\r\\nIt will show the name and the enabled status.\\nA result set example:\\nFlightName                         Enabled FlightServiceId\\r\\n----------                         ------- ---------------\\r\\nWHSWorkCancelForcedFlight          1       12719367\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365Flight -FlightName WHS*\\nThis will list the flight with the specified pattern on the environment.\\r\\nIt will filter the output to match the \\\"WHS*\\\" pattern.\\r\\nIt will show the name and the enabled status.\\nA result set example:\\nFlightName                         Enabled FlightServiceId\\r\\n----------                         ------- ---------------\\r\\nWHSWorkCancelForcedFlight          1       12719367\",\n        \"Syntax\":  \"Get-D365Flight [[-FlightName] \\u003cString\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365IISPreload\",\n        \"Description\":  \"Returns the current IIS Preload configuration for the AOSService application:\\n- Application Pool Start Mode\\n- Idle Time-out\\n- Website Preload Enabled\\n- doAppInitAfterRestart (if Application Initialization is installed)\",\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Florian Hopfner (FH-Inway)\",\n        \"Synopsis\":  \"Gets IIS Preload status for the AOSService application pool and website.\",\n        \"Name\":  \"Get-D365IISPreload\",\n        \"Links\":  [\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365IISPreload\\nRetrieves the IIS Preload configuration for the AOSService application pool and website.\",\n        \"Syntax\":  \"Get-D365IISPreload [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365InstalledHotfix\",\n        \"Description\":  \"Get all relevant details for installed hotfixes on environments that are not on a \\\"One Version\\\" version. This cmdlet is deprecated since 2021-10-05 and will be removed by 2022-04-05.\",\n        \"Tags\":  [\n                     \"Hotfix\",\n                     \"Servicing\",\n                     \"Model\",\n                     \"Models\",\n                     \"KB\",\n                     \"Patch\",\n                     \"Patching\",\n                     \"PackagesLocalDirectory\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the AOS Service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the PackagesLocalDirectory\\nDefault path is the same as the AOS Service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ],\n                       [\n                           \"Model\",\n                           \"Name of the model that you want to work against\\nAccepts wildcards for searching. E.g. -Model \\\"*Retail*\\\"\\nDefault value is \\\"*\\\" which will search for all models\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"Name\",\n                           \"Name of the hotfix that you are looking for\\nAccepts wildcards for searching. E.g. -Name \\\"7045*\\\"\\nDefault value is \\\"*\\\" which will search for all hotfixes\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"KB\",\n                           \"KB number of the hotfix that you are looking for\\nAccepts wildcards for searching. E.g. -KB \\\"4045*\\\"\\nDefault value is \\\"*\\\" which will search for all KB\\u0027s\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get installed hotfix (DEPRECATED)\",\n        \"Name\":  \"Get-D365InstalledHotfix\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365InstalledHotfix\\nThis will display all installed hotfixes found on this machine\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365InstalledHotfix -Model \\\"*retail*\\\"\\nThis will display all installed hotfixes found for all models that matches the search for \\\"*retail*\\\" found on this machine\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365InstalledHotfix -Model \\\"*retail*\\\" -KB \\\"*43*\\\"\\nThis will display all installed hotfixes found for all models that matches the search for \\\"*retail*\\\" and only with KB\\u0027s that matches the search for \\\"*43*\\\" found on this machine\",\n        \"Syntax\":  \"Get-D365InstalledHotfix [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [[-Model] \\u003cString\\u003e] [[-Name] \\u003cString\\u003e] [[-KB] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365InstalledPackage\",\n        \"Description\":  \"Get installed package from the machine running the AOS service for Dynamics 365 Finance \\u0026 Operations\",\n        \"Tags\":  [\n                     \"PackagesLocalDirectory\",\n                     \"Servicing\",\n                     \"Model\",\n                     \"Models\",\n                     \"Package\",\n                     \"Packages\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"Name of the package that you are looking for\\nAccepts wildcards for searching. E.g. -Name \\\"Application*Adaptor\\\"\\nDefault value is \\\"*\\\" which will search for all packages\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed packages\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get installed package from Dynamics 365 Finance \\u0026 Operations environment\",\n        \"Name\":  \"Get-D365InstalledPackage\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365InstalledPackage\\nShows the entire list of installed packages located in the default location on the machine\\nA result set example:\\r\\nApplicationFoundationFormAdaptor\\r\\nApplicationPlatformFormAdaptor\\r\\nApplicationSuiteFormAdaptor\\r\\nApplicationWorkspacesFormAdaptor\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365InstalledPackage -Name \\\"Application*Adaptor\\\"\\nShows the list of installed packages where the name fits the search \\\"Application*Adaptor\\\"\\nA result set example:\\r\\nApplicationFoundationFormAdaptor\\r\\nApplicationPlatformFormAdaptor\\r\\nApplicationSuiteFormAdaptor\\r\\nApplicationWorkspacesFormAdaptor\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365InstalledPackage -PackageDirectory \\\"J:\\\\AOSService\\\\PackagesLocalDirectory\\\"\\nShows the entire list of installed packages located in \\\"J:\\\\AOSService\\\\PackagesLocalDirectory\\\" on the machine\\nA result set example:\\r\\nApplicationFoundationFormAdaptor\\r\\nApplicationPlatformFormAdaptor\\r\\nApplicationSuiteFormAdaptor\\r\\nApplicationWorkspacesFormAdaptor\",\n        \"Syntax\":  \"Get-D365InstalledPackage [[-Name] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365InstalledService\",\n        \"Description\":  \"Get installed Dynamics 365 for Finance \\u0026 Operations services that are installed on the machine\",\n        \"Tags\":  [\n                     \"Services\",\n                     \"Servicing\",\n                     \"Topology\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the folder that contains the \\\"InstallationRecords\\\" folder\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:InstallationRecordsDir\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get installed D365 services\",\n        \"Name\":  \"Get-D365InstalledService\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365InstalledService\\nThis will get all installed services on the machine.\",\n        \"Syntax\":  \"Get-D365InstalledService [[-Path] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365InstanceName\",\n        \"Description\":  \"Get the instance name that is registered in the environment\",\n        \"Tags\":  [\n                     \"Instance\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Rasmus Andersen (@ITRasmus)\",\n        \"Synopsis\":  \"Gets the instance name\",\n        \"Name\":  \"Get-D365InstanceName\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365InstanceName\\nThis will get the service name that the environment has configured\",\n        \"Syntax\":  \"Get-D365InstanceName [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365JsonService\",\n        \"Description\":  \"Get Json based services that are available from a Dynamics 365 Finance \\u0026 Operations environment\",\n        \"Tags\":  [\n                     \"DMF\",\n                     \"OData\",\n                     \"RestApi\",\n                     \"Data Management Framework\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"The name of the json service that you are looking for\\nDefault value is \\\"*\\\" to display all json services\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"Url\",\n                           \"URL / URI for the D365FO environment you want to access\\nIf you are working against a D365FO instance, it will be the URL / URI for the instance itself\\nIf you are working against a D365 Talent / HR instance, this will have to be \\\"http://hr.talent.dynamics.com\\\"\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Tenant\",\n                           \"Azure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to access\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ClientId\",\n                           \"The ClientId obtained from the Azure Portal when you created a Registered Application\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ClientSecret\",\n                           \"The ClientSecret obtained from the Azure Portal when you created a Registered Application\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"RawOutput\",\n                           \"Instructs the cmdlet to include the outer structure of the response received from the endpoint\\nThe output will still be a PSCustomObject\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputAsJson\",\n                           \"Instructs the cmdlet to convert the output to a Json string\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get Json based service\",\n        \"Name\":  \"Get-D365JsonService\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365JsonService -Url \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\" -Tenant \\\"e674da86-7ee5-40a7-b777-1111111111111\\\" -ClientId \\\"dea8d7a9-1602-4429-b138-111111111111\\\" -ClientSecret \\r\\n\\\"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\\\"\\nThis will get all available service groups for the D365FO instance.\\r\\nIt will contact the D365FO instance specified in the Url parameter: \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\".\\r\\nIt will authenticate againt the \\\"https://login.microsoftonline.com/e674da86-7ee5-40a7-b777-1111111111111/oauth2/token\\\" url with the specified Tenant parameter: \\\"e674da86-7ee5-40a7-b777-1111111111111\\\".\\r\\nIt will authenticate with the specified ClientId parameter: \\\"dea8d7a9-1602-4429-b138-111111111111\\\".\\r\\nIt will authenticate with the specified ClientSecret parameter: \\\"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\\\".\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365JsonService -Name \\\"*TS*\\\" -Url \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\" -Tenant \\\"e674da86-7ee5-40a7-b777-1111111111111\\\" -ClientId \\\"dea8d7a9-1602-4429-b138-111111111111\\\" \\r\\n-ClientSecret \\\"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\\\"\\nThis will get all available service groups for the D365FO instance, which matches the \\\"*TS*\\\" as a name.\\r\\nIt will contact the D365FO instance specified in the Url parameter: \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\".\\r\\nIt will authenticate againt the \\\"https://login.microsoftonline.com/e674da86-7ee5-40a7-b777-1111111111111/oauth2/token\\\" url with the specified Tenant parameter: \\\"e674da86-7ee5-40a7-b777-1111111111111\\\".\\r\\nIt will authenticate with the specified ClientId parameter: \\\"dea8d7a9-1602-4429-b138-111111111111\\\".\\r\\nIt will authenticate with the specified ClientSecret parameter: \\\"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\\\".\\r\\nIt will limit the output to only those matching the specified Name parameter: \\\"*TS*\\\"\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365JsonService -Url \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\" -Tenant \\\"e674da86-7ee5-40a7-b777-1111111111111\\\" -ClientId \\\"dea8d7a9-1602-4429-b138-111111111111\\\" -ClientSecret \\r\\n\\\"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\\\" -RawOutput\\nThis will get all available service groups for the D365FO instance with the outer most hierarchy.\\r\\nIt will contact the D365FO instance specified in the Url parameter: \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\".\\r\\nIt will authenticate againt the \\\"https://login.microsoftonline.com/e674da86-7ee5-40a7-b777-1111111111111/oauth2/token\\\" url with the specified Tenant parameter: \\\"e674da86-7ee5-40a7-b777-1111111111111\\\".\\r\\nIt will authenticate with the specified ClientId parameter: \\\"dea8d7a9-1602-4429-b138-111111111111\\\".\\r\\nIt will authenticate with the specified ClientSecret parameter: \\\"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\\\".\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365JsonService -Url \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\" -Tenant \\\"e674da86-7ee5-40a7-b777-1111111111111\\\" -ClientId \\\"dea8d7a9-1602-4429-b138-111111111111\\\" -ClientSecret \\r\\n\\\"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\\\" -OutputAsJson\\nThis will get all available service groups for the D365FO instance and display the result as json.\\r\\nIt will contact the D365FO instance specified in the Url parameter: \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\".\\r\\nIt will authenticate againt the \\\"https://login.microsoftonline.com/e674da86-7ee5-40a7-b777-1111111111111/oauth2/token\\\" url with the specified Tenant parameter: \\\"e674da86-7ee5-40a7-b777-1111111111111\\\".\\r\\nIt will authenticate with the specified ClientId parameter: \\\"dea8d7a9-1602-4429-b138-111111111111\\\".\\r\\nIt will authenticate with the specified ClientSecret parameter: \\\"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\\\".\",\n        \"Syntax\":  \"Get-D365JsonService [[-Name] \\u003cString\\u003e] [-Url] \\u003cString\\u003e [-Tenant] \\u003cString\\u003e [-ClientId] \\u003cString\\u003e [-ClientSecret] \\u003cString\\u003e [-RawOutput] [-OutputAsJson] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365Label\",\n        \"Description\":  \"Get label from the label file from the running the Dynamics 365 Finance \\u0026 Operations instance\",\n        \"Tags\":  [\n                     \"PackagesLocalDirectory\",\n                     \"Servicing\",\n                     \"Language\",\n                     \"Labels\",\n                     \"Label\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the AOS service PackagesLocalDirectory\\\\bin\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"LabelFileId\",\n                           \"Name / Id of the label \\\"file\\\" that you want to work against\",\n                           \"\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"Language\",\n                           \"Name / string representation of the language / culture you want to work against\\nDefault value is \\\"en-US\\\"\",\n                           \"\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"en-US\"\n                       ],\n                       [\n                           \"Name\",\n                           \"Name of the label that you are looking for\\nAccepts wildcards for searching. E.g. -Name \\\"@PRO59*\\\"\\nDefault value is \\\"*\\\" which will search for all labels\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get label from the label file from Dynamics 365 Finance \\u0026 Operations environment\",\n        \"Name\":  \"Get-D365Label\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365Label -LabelFileId PRO\\nShows the entire list of labels that are available from the PRO label file.\\r\\nThe language is defaulted to \\\"en-US\\\".\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365Label -LabelFileId PRO -Language da\\nShows the entire list of labels that are available from the PRO label file.\\r\\nShows only all \\\"da\\\" (Danish) labels.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365Label -LabelFileId PRO -Name \\\"@PRO59*\\\"\\nShows the labels available from the PRO label file where the name fits the search \\\"@PRO59*\\\"\\nA result set example:\\nName                 Value                                                                            Language\\r\\n----                 -----                                                                            --------\\r\\n@PRO59               Indicates if the type of the rebate value.                                       en-US\\r\\n@PRO594              Pack consumption                                                                 en-US\\r\\n@PRO595              Pack qty now being released to production in the BOM unit.                       en-US\\r\\n@PRO596              Pack unit.                                                                       en-US\\r\\n@PRO597              Pack proposal for release in the packing unit.                                   en-US\\r\\n@PRO590              Constant pack qty                                                                en-US\\r\\n@PRO593              Pack proposal release in BOM unit.                                               en-US\\r\\n@PRO598              Pack quantity now being released for the production in the packing unit.         en-US\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365Label -LabelFileId PRO -Name \\\"@PRO59*\\\" -Language da,en-us\\nShows the labels available from the PRO label file where the name fits the search \\\"@PRO59*\\\".\\r\\nShows for both \\\"da\\\" (Danish) and en-US (English)\",\n        \"Syntax\":  \"Get-D365Label [[-BinDir] \\u003cString\\u003e] [-LabelFileId] \\u003cString\\u003e [[-Language] \\u003cString[]\\u003e] [[-Name] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365LabelFile\",\n        \"Description\":  \"Get label file (ids) for packages / modules from the machine running the AOS service for Dynamics 365 Finance \\u0026 Operations\",\n        \"Tags\":  [\n                     \"PackagesLocalDirectory\",\n                     \"Servicing\",\n                     \"Language\",\n                     \"Labels\",\n                     \"Label\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the AOS service PackagesLocalDirectory\\\\bin\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ],\n                       [\n                           \"Module\",\n                           \"Name of the module that you want to work against\\nDefault value is \\\"*\\\" which will search for all modules\",\n                           \"ModuleName\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"*\"\n                       ],\n                       [\n                           \"Name\",\n                           \"Name of the label file (id) that you are looking for\\nAccepts wildcards for searching. E.g. -Name \\\"Acc*Receivable*\\\"\\nDefault value is \\\"*\\\" which will search for all label file (ids)\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get label file (ids) for packages / modules from Dynamics 365 Finance \\u0026 Operations environment\",\n        \"Name\":  \"Get-D365LabelFile\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365LabelFile\\nShows the entire list of label file (ids) for all installed packages / modules located in the default location on the machine\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365LabelFile -Name \\\"Acc*Receivable*\\\"\\nShows the list of label file (ids) for all installed packages / modules where the label file (ids) name fits the search \\\"Acc*Receivable*\\\"\\nA result set example:\\nLabelFileId                        Languages              Module\\r\\n-----------                        ---------              ------\\r\\nAccountsReceivable                 {ar-AE, ar, cs, da...} ApplicationSuite\\r\\nAccountsReceivable_SalesTaxCodesSA {en-US}                ApplicationSuite\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365LabelFile -PackageDirectory \\\"J:\\\\AOSService\\\\PackagesLocalDirectory\\\"\\nShows the list of label file (ids) for all installed packages / modules located in \\\"J:\\\\AOSService\\\\PackagesLocalDirectory\\\" on the machine\",\n        \"Syntax\":  \"Get-D365LabelFile [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [[-Module] \\u003cString\\u003e] [[-Name] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365Language\",\n        \"Description\":  \"Get installed languages from the running the Dynamics 365 Finance \\u0026 Operations instance\",\n        \"Tags\":  [\n                     \"PackagesLocalDirectory\",\n                     \"Servicing\",\n                     \"Language\",\n                     \"Labels\",\n                     \"Label\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"BinDir\",\n                           \"Path to the directory containing the BinDir and its assemblies\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"Name\",\n                           \"Name of the language that you are looking for\\nAccepts wildcards for searching. E.g. -Name \\\"fr*\\\"\\nDefault value is \\\"*\\\" which will search for all languages\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get installed languages from Dynamics 365 Finance \\u0026 Operations environment\",\n        \"Name\":  \"Get-D365Language\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365Language\\nShows the entire list of installed languages that are available from the running instance\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365Language -Name \\\"fr*\\\"\\nShows the list of installed languages where the name fits the search \\\"fr*\\\"\\nA result set example:\\r\\nfr      French\\r\\nfr-BE   French (Belgium)\\r\\nfr-CA   French (Canada)\\r\\nfr-CH   French (Switzerland)\",\n        \"Syntax\":  \"Get-D365Language [[-BinDir] \\u003cString\\u003e] [[-Name] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365LcsApiConfig\",\n        \"Description\":  \"Get the LCS configuration details from the configuration store\\n\\nAll settings retrieved from this cmdlets is to be considered the default parameter values across the different cmdlets\",\n        \"Tags\":  [\n                     \"Environment\",\n                     \"Url\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"LCS\",\n                     \"Upload\",\n                     \"ClientId\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputAsHashtable\",\n                           \"Instruct the cmdlet to return a hashtable object\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the LCS configuration details\",\n        \"Name\":  \"Get-D365LcsApiConfig\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsApiConfig\\nThis will output the current LCS API configuration.\\r\\nThe object returned will be a PSCustomObject.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsApiConfig -OutputAsHashtable\\nThis will output the current LCS API configuration.\\r\\nThe object returned will be a Hashtable.\",\n        \"Syntax\":  \"Get-D365LcsApiConfig [-OutputAsHashtable] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365LcsApiToken\",\n        \"Description\":  \"Get a valid OAuth 2.0 access token for LCS, by providing an easy way to work against the Azure AD of your tenant\",\n        \"Tags\":  [\n                     \"Environment\",\n                     \"Url\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"LCS\",\n                     \"Upload\",\n                     \"Api\",\n                     \"AAD\",\n                     \"Token\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"ClientId\",\n                           \"The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiClientId\"\n                       ],\n                       [\n                           \"Username\",\n                           \"The username of the account that you want to impersonate\\nIt can either be your personal account or a service account\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Password\",\n                           \"The password of the account that you want to impersonate\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get a valid OAuth 2.0 access token for LCS\",\n        \"Name\":  \"Get-D365LcsApiToken\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsApiToken -ClientId \\\"9b4f4503-b970-4ade-abc6-2c086e4c4929\\\" -Username \\\"serviceaccount@domain.com\\\" -Password \\\"TopSecretPassword\\\" -LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\"\\nThis will obtain a valid OAuth 2.0 access token from Azure Active Directory.\\r\\nThe ClientId \\\"9b4f4503-b970-4ade-abc6-2c086e4c4929\\\" is used in the OAuth 2.0 Grant Flow to authenticate.\\r\\nThe Username \\\"serviceaccount@domain.com\\\" and Password \\\"TopSecretPassword\\\" is used in the OAuth 2.0 Grant Flow, to approved that the application should impersonate like \\\"serviceaccount@domain.com\\\".\\r\\nThe http request will be going to the LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\" (NON-EUROPE).\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsApiToken -ClientId \\\"9b4f4503-b970-4ade-abc6-2c086e4c4929\\\" -Username \\\"serviceaccount@domain.com\\\" -Password \\\"TopSecretPassword\\\" -LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\" | \\r\\nSet-D365LcsApiConfig -ProjectId 123456789\\nThis will obtain a valid OAuth 2.0 access token from Azure Active Directory.\\r\\nThe ClientId \\\"9b4f4503-b970-4ade-abc6-2c086e4c4929\\\" is used in the OAuth 2.0 Grant Flow to authenticate.\\r\\nThe Username \\\"serviceaccount@domain.com\\\" and Password \\\"TopSecretPassword\\\" is used in the OAuth 2.0 Grant Flow, to approved that the application should impersonate like \\\"serviceaccount@domain.com\\\".\\r\\nThe http request will be going to the LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\" (NON-EUROPE).\\nThe output object received from Get-D365LcsApiToken is piped directly to Set-D365LcsApiConfig.\\nSet-D365LcsApiConfig will save the ClientId, LcsApiUri, ProjectId, access_token(BearerToken), refresh_token(RefreshToken), expires_on(ActiveTokenExpiresOn) details for the module to use them across \\r\\nother LCS cmdlets.\\nThis should be your default approach in using and leveraging the module, so you don\\u0027t have to supply the same parameters for every single cmdlet.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsApiToken -Username \\\"serviceaccount@domain.com\\\" -Password \\\"TopSecretPassword\\\"\\nThis will obtain a valid OAuth 2.0 access token from Azure Active Directory.\\r\\nThe Username \\\"serviceaccount@domain.com\\\" and Password \\\"TopSecretPassword\\\" is used in the OAuth 2.0 Grant Flow, to approved that the application should impersonate like \\\"serviceaccount@domain.com\\\".\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsApiToken -Username \\\"serviceaccount@domain.com\\\" -Password \\\"TopSecretPassword\\\" | Set-D365LcsApiConfig\\nThis will obtain a valid OAuth 2.0 access token from Azure Active Directory and save the needed details.\\r\\nThe Username \\\"serviceaccount@domain.com\\\" and Password \\\"TopSecretPassword\\\" is used in the OAuth 2.0 Grant Flow, to approved that the application should impersonate like \\\"serviceaccount@domain.com\\\".\\r\\nThe output object received from Get-D365LcsApiToken is piped directly to Set-D365LcsApiConfig.\\r\\nSet-D365LcsApiConfig will save the access_token(BearerToken), refresh_token(RefreshToken) and expires_on(ActiveTokenExpiresOn).\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\",\n        \"Syntax\":  \"Get-D365LcsApiToken [[-ClientId] \\u003cString\\u003e] [-Username] \\u003cString\\u003e [-Password] \\u003cString\\u003e [[-LcsApiUri] \\u003cString\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365LcsAssetFile\",\n        \"Description\":  \"Get the available files from the Asset Library in LCS project\",\n        \"Params\":  [\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiProjectId\"\n                       ],\n                       [\n                           \"FileType\",\n                           \"Type of file you want to list from the LCS Asset Library\\nValid options:\\r\\n\\\"Model\\\"\\r\\n\\\"Process Data Package\\\"\\r\\n\\\"Software Deployable Package\\\"\\r\\n\\\"GER Configuration\\\"\\r\\n\\\"Data Package\\\"\\r\\n\\\"PowerBI Report Model\\\"\\r\\n\\\"E-Commerce Package\\\"\\r\\n\\\"NuGet Package\\\"\\r\\n\\\"Retail Self-Service Package\\\"\\r\\n\\\"Commerce Cloud Scale Unit Extension\\\"\\nDefault value is \\\"Software Deployable Package\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"SoftwareDeployablePackage\"\n                       ],\n                       [\n                           \"AssetName\",\n                           \"Name of the asset that you are looking for\\nAccepts wildcards for searching. E.g. -AssetName \\\"*ISV*\\\"\\nDefault value is \\\"*\\\" which will search for all assets via the Name property\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"AssetVersion\",\n                           \"Version of the Asset file that you are looking for\\nIt does a simple compare against the response from LCS and only lists the ones that matches\\nAccepts wildcards for searching. E.g. -AssetVersion \\\"*ISV*\\\"\\nDefault value is \\\"*\\\" which will search for all files\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"AssetFilename\",\n                           \"Name of the file that you are looking for\\nAccepts wildcards for searching. E.g. -AssetFilename \\\"*ISV*\\\"\\nDefault value is \\\"*\\\" which will search for all files via the FileName property\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"AssetDescription\",\n                           \"Name of the file that you are looking for\\nAccepts wildcards for searching. E.g. -AssetDescription \\\"*ISV*\\\"\\nDefault value is \\\"*\\\" which will search for all files via the FileDescription property\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"AssetId\",\n                           \"Id of the file that you are looking for\\nAccepts wildcards for searching. E.g. -AssetId \\\"*ISV*\\\"\\nDefault value is \\\"*\\\" which will search for all files via the AssetId property\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"Token\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiBearerToken\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"Latest\",\n                           \"Instruct the cmdlet to only fetch the latest file from the Asset Library from LCS\",\n                           \"GetLatest\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"RetryTimeout\",\n                           \"The retry timeout, before the cmdlet should quit retrying based on the 429 status code\\nNeeds to be provided in the timspan notation:\\r\\n\\\"hh:mm:ss\\\"\\nhh is the number of hours, numerical notation only\\r\\nmm is the number of minutes\\r\\nss is the numbers of seconds\\nEach section of the timeout has to valid, e.g.\\r\\nhh can maximum be 23\\r\\nmm can maximum be 59\\r\\nss can maximum be 59\\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"00:00:00\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get file from the Asset library inside the LCS project\",\n        \"Name\":  \"Get-D365LcsAssetFile\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsAssetFile -ProjectId 123456789 -FileType SoftwareDeployablePackage -BearerToken \\\"JldjfafLJdfjlfsalfd...\\\" -LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\"\\nThis will list all Software Deployable Packages.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe request will authenticate with the BearerToken \\\"JldjfafLJdfjlfsalfd...\\\".\\r\\nThe http request will be going to the LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\" (NON-EUROPE).\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsAssetFile -FileType SoftwareDeployablePackage\\nThis will list all Software Deployable Packages.\\r\\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetFilename \\\"*MAIN*\\\"\\nThis will list all Software Deployable Packages, that matches the \\\"*MAIN*\\\" search pattern in the AssetFilename.\\r\\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\\r\\nIt will filter the output to match the AssetFilename \\\"*MAIN*\\\" search pattern.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetName \\\"*MAIN*\\\"\\nThis will list all Software Deployable Packages, that matches the \\\"*MAIN*\\\" search pattern in the AssetName.\\r\\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\\r\\nIt will filter the output to match the AssetName \\\"*MAIN*\\\" search pattern.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetDescription \\\"*TEST*\\\"\\nThis will list all Software Deployable Packages, that matches the \\\"*TEST*\\\" search pattern in the AssetDescription.\\r\\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\\r\\nIt will filter the output to match the AssetDescription \\\"*TEST*\\\" search pattern.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 6 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetId \\\"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\\\"\\nThis will list all Software Deployable Packages, that matches the \\\"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\\\" search pattern in the AssetId.\\r\\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\\r\\nIt will filter the output to match the AssetId \\\"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\\\" search pattern.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 7 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -Latest | Invoke-D365AzCopyTransfer -DestinationUri C:\\\\Temp\\\\d365fo.tools -FileName \\\"Main.zip\\\" -ShowOriginalProgress\\nThis will download the latest Software Deployable Package from the Asset Library in LCS onto your on machine.\\r\\nIt will list Software Deployable Packages based on the FileType parameter.\\r\\nIt will list the latest (newest) Software Deployable Package.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 8 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -RetryTimeout \\\"00:01:00\\\"\\nThis will list all Software Deployable Packages, and allow for the cmdlet to retry for no more than 1 minute.\\r\\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\",\n        \"Syntax\":  \"Get-D365LcsAssetFile [[-ProjectId] \\u003cInt32\\u003e] [[-FileType] {Model | ProcessDataPackage | SoftwareDeployablePackage | GERConfiguration | DataPackage | PowerBIReportModel | ECommercePackage | NuGetPackage | RetailSelfServicePackage | CommerceCloudScaleUnitExtension}] [[-AssetName] \\u003cString\\u003e] [[-AssetVersion] \\u003cString\\u003e] [[-AssetFilename] \\u003cString\\u003e] [[-AssetDescription] \\u003cString\\u003e] [[-AssetId] \\u003cString\\u003e] [[-BearerToken] \\u003cString\\u003e] [[-LcsApiUri] \\u003cString\\u003e] [-Latest] [[-RetryTimeout] \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365LcsAssetValidationStatus\",\n        \"Description\":  \"Get the validation status for a given file in the Asset Library in LCS\",\n        \"Params\":  [\n                       [\n                           \"AssetId\",\n                           \"The unique id of the asset / file that you are trying to deploy from LCS\",\n                           \"\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiProjectId\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"Token\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiBearerToken\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"WaitForValidation\",\n                           \"Instruct the cmdlet to wait for the validation process to complete\\nThe cmdlet will sleep for 60 seconds, before requesting the status of the validation process from LCS\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"SleepInSeconds\",\n                           \"Time in seconds that you want the cmdlet to use as the sleep timer between each request against the LCS endpoint\\nDefault value is 60\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"60\"\n                       ],\n                       [\n                           \"RetryTimeout\",\n                           \"The retry timeout, before the cmdlet should quit retrying based on the 429 status code\\nNeeds to be provided in the timspan notation:\\r\\n\\\"hh:mm:ss\\\"\\nhh is the number of hours, numerical notation only\\r\\nmm is the number of minutes\\r\\nss is the numbers of seconds\\nEach section of the timeout has to valid, e.g.\\r\\nhh can maximum be 23\\r\\nmm can maximum be 59\\r\\nss can maximum be 59\\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"00:00:00\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the validation status from LCS\",\n        \"Name\":  \"Get-D365LcsAssetValidationStatus\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsAssetValidationStatus -ProjectId 123456789 -BearerToken \\\"JldjfafLJdfjlfsalfd...\\\" -AssetId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\"\\nThis will check the validation status for the file in the Asset Library.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe file is identified by the AssetId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which is obtained either by earlier upload or simply looking in the LCS portal.\\r\\nThe request will authenticate with the BearerToken \\\"Bearer JldjfafLJdfjlfsalfd...\\\".\\r\\nThe http request will be going to the LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\" (NON-EUROPE).\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsAssetValidationStatus -AssetId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\"\\nThis will check the validation status for the file in the Asset Library.\\r\\nThe file is identified by the AssetId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which is obtained either by earlier upload or simply looking in the LCS portal.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsAssetValidationStatus -AssetId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -WaitForValidation\\nThis will check the validation status for the file in the Asset Library.\\r\\nThe file is identified by the AssetId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which is obtained either by earlier upload or simply looking in the LCS portal.\\r\\nThe cmdlet will every 60 seconds contact the LCS API endpoint and check if the status of the validation is either success or failure.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsUpload -FilePath \\\"C:\\\\temp\\\\d365fo.tools\\\\Release-2019-05-05.zip\\\" | Get-D365LcsAssetValidationStatus -WaitForValidation\\nThis will start the upload of a file to the Asset Library and check the validation status for the file in the Asset Library.\\r\\nThe file that will be uploaded is based on the FilePath \\\"C:\\\\temp\\\\d365fo.tools\\\\Release-2019-05-05.zip\\\".\\r\\nThe output object received from Invoke-D365LcsUpload is piped directly to Get-D365LcsAssetValidationStatus.\\r\\nThe cmdlet will every 60 seconds contact the LCS API endpoint and check if the status of the validation is either success or failure.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsAssetValidationStatus -AssetId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -RetryTimeout \\\"00:01:00\\\"\\nThis will check the validation status for the file in the Asset Library, and allow for the cmdlet to retry for no more than 1 minute.\\r\\nThe file is identified by the AssetId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which is obtained either by earlier upload or simply looking in the LCS portal.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\",\n        \"Syntax\":  \"Get-D365LcsAssetValidationStatus [-AssetId] \\u003cString\\u003e [[-ProjectId] \\u003cInt32\\u003e] [[-BearerToken] \\u003cString\\u003e] [[-LcsApiUri] \\u003cString\\u003e] [-WaitForValidation] [[-SleepInSeconds] \\u003cInt32\\u003e] [[-RetryTimeout] \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365LcsDatabaseBackups\",\n        \"Description\":  \"Get the available database backups from the Asset Library in LCS project\",\n        \"Params\":  [\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiProjectId\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"Token\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiBearerToken\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"Latest\",\n                           \"Instruct the cmdlet to only fetch the latest file from the Azure Storage Account\",\n                           \"GetLatest\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"RetryTimeout\",\n                           \"The retry timeout, before the cmdlet should quit retrying based on the 429 status code\\nNeeds to be provided in the timspan notation:\\r\\n\\\"hh:mm:ss\\\"\\nhh is the number of hours, numerical notation only\\r\\nmm is the number of minutes\\r\\nss is the numbers of seconds\\nEach section of the timeout has to valid, e.g.\\r\\nhh can maximum be 23\\r\\nmm can maximum be 59\\r\\nss can maximum be 59\\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"00:00:00\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get database backups from LCS project\",\n        \"Name\":  \"Get-D365LcsDatabaseBackups\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsDatabaseBackups -ProjectId 123456789 -BearerToken \\\"JldjfafLJdfjlfsalfd...\\\" -LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\"\\nThis will get all available database backups from the Asset Library inside LCS.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe request will authenticate with the BearerToken \\\"Bearer JldjfafLJdfjlfsalfd...\\\".\\r\\nThe http request will be going to the LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\" (NON-EUROPE).\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsDatabaseBackups\\nThis will get all available database backups from the Asset Library inside LCS.\\r\\nIt will use default values for all parameters.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsDatabaseBackups -Latest\\nThis will get the latest available database backup from the Asset Library inside LCS.\\r\\nIt will use default values for all parameters.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsDatabaseBackups -Latest -RetryTimeout \\\"00:01:00\\\"\\nThis will get the latest available database backup from the Asset Library inside LCS, and allow for the cmdlet to retry for no more than 1 minute.\\r\\nIt will use default values for all parameters.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\",\n        \"Syntax\":  \"Get-D365LcsDatabaseBackups [[-ProjectId] \\u003cInt32\\u003e] [[-BearerToken] \\u003cString\\u003e] [[-LcsApiUri] \\u003cString\\u003e] [-Latest] [[-RetryTimeout] \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365LcsDatabaseOperationStatus\",\n        \"Description\":  \"Get the current status of a database operation against an environment from a LCS project\",\n        \"Tags\":  [\n                     \"Environment\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"LCS\",\n                     \"Database backup\",\n                     \"Api\",\n                     \"Backup\",\n                     \"Restore\",\n                     \"Refresh\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiProjectId\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"Token\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiBearerToken\"\n                       ],\n                       [\n                           \"OperationActivityId\",\n                           \"The unique id of the operaction activity that identitfies the database operation\\nIt will be part of the output from the different Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets\",\n                           \"ActivityId\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"EnvironmentId\",\n                           \"The unique id of the environment that you want to work against\\nThe Id can be located inside the LCS portal\",\n                           \"SourceEnvironmentId\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"WaitForCompletion\",\n                           \"Instruct the cmdlet to wait for the deployment process to complete\\nThe cmdlet will sleep for 300 seconds, before requesting the status of the deployment process from LCS\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"SleepInSeconds\",\n                           \"Time in seconds that you want the cmdlet to use as the sleep timer between each request against the LCS endpoint\\nDefault value is 300\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"300\"\n                       ],\n                       [\n                           \"RetryTimeout\",\n                           \"The retry timeout, before the cmdlet should quit retrying based on the 429 status code\\nNeeds to be provided in the timspan notation:\\r\\n\\\"hh:mm:ss\\\"\\nhh is the number of hours, numerical notation only\\r\\nmm is the number of minutes\\r\\nss is the numbers of seconds\\nEach section of the timeout has to valid, e.g.\\r\\nhh can maximum be 23\\r\\nmm can maximum be 59\\r\\nss can maximum be 59\\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"00:00:00\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the status of a database operation from LCS\",\n        \"Name\":  \"Get-D365LcsDatabaseOperationStatus\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsDatabaseOperationStatus -ProjectId 123456789 -OperationActivityId 123456789 -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -BearerToken \\\"JldjfafLJdfjlfsalfd...\\\" -LcsApiUri \\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\nThis will check the database operation status of a specific OperationActivityId against an environment.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\r\\nThe request will authenticate with the BearerToken \\\"JldjfafLJdfjlfsalfd...\\\".\\r\\nThe http request will be going to the LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\" (NON-EUROPE).\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsDatabaseOperationStatus -OperationActivityId 123456789 -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\"\\nThis will check the database operation status of a specific OperationActivityId against an environment.\\r\\nThe OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsDatabaseOperationStatus -OperationActivityId 123456789 -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -WaitForCompletion\\nThis will check the database operation status of a specific OperationActivityId against an environment.\\r\\nThe OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\r\\nThe cmdlet will every 300 seconds contact the LCS API endpoint and check if the status of the database operation status is either success or failure.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsDatabaseOperationStatus -OperationActivityId 123456789 -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -RetryTimeout \\\"00:01:00\\\"\\nThis will check the database operation status of a specific OperationActivityId against an environment, and allow for the cmdlet to retry for no more than 1 minute.\\r\\nThe OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\",\n        \"Syntax\":  \"Get-D365LcsDatabaseOperationStatus [[-ProjectId] \\u003cInt32\\u003e] [[-BearerToken] \\u003cString\\u003e] [-OperationActivityId] \\u003cString\\u003e [-EnvironmentId] \\u003cString\\u003e [[-LcsApiUri] \\u003cString\\u003e] [-WaitForCompletion] [[-SleepInSeconds] \\u003cInt32\\u003e] [[-RetryTimeout] \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365LcsDeploymentStatus\",\n        \"Description\":  \"Get the Deployment status for activity against an environment from the Dynamics LCS Portal\",\n        \"Tags\":  [\n                     \"Environment\",\n                     \"Url\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"LCS\",\n                     \"Upload\",\n                     \"Api\",\n                     \"AAD\",\n                     \"Token\",\n                     \"Deployment\",\n                     \"Deploy\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiProjectId\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"Token\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiBearerToken\"\n                       ],\n                       [\n                           \"ActivityId\",\n                           \"The unique id of the action that you started from the Invoke-D365LcsDeployment cmdlet\",\n                           \"ActionHistoryId\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"EnvironmentId\",\n                           \"The unique id of the environment that you want to work against\\nThe Id can be located inside the LCS portal\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"WaitForCompletion\",\n                           \"Instruct the cmdlet to wait for the deployment process to complete\\nThe cmdlet will sleep for 300 seconds, before requesting the status of the deployment process from LCS\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"SleepInSeconds\",\n                           \"Time in secounds that you want the cmdlet to use as the sleep timer between each request against the LCS endpoint\\nDefault value is 300\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"300\"\n                       ],\n                       [\n                           \"FailOnErrorMessage\",\n                           \"Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\\r\\nThis allows you to implement custom retry / error handling logic\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"RetryTimeout\",\n                           \"The retry timeout, before the cmdlet should quit retrying based on the 429 status code\\nNeeds to be provided in the timspan notation:\\r\\n\\\"hh:mm:ss\\\"\\nhh is the number of hours, numerical notation only\\r\\nmm is the number of minutes\\r\\nss is the numbers of seconds\\nEach section of the timeout has to valid, e.g.\\r\\nhh can maximum be 23\\r\\nmm can maximum be 59\\r\\nss can maximum be 59\\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"00:00:00\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the Deployment status from LCS\",\n        \"Name\":  \"Get-D365LcsDeploymentStatus\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsDeploymentStatus -ProjectId 123456789 -ActivityId 123456789 -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -BearerToken \\\"Bearer JldjfafLJdfjlfsalfd...\\\" -LcsApiUri \\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\nThis will check the deployment status of specific activity against an environment.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\r\\nThe request will authenticate with the BearerToken \\\"Bearer JldjfafLJdfjlfsalfd...\\\".\\r\\nThe http request will be going to the LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\" (NON-EUROPE).\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsDeploymentStatus -ActivityId 123456789 -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\"\\nThis will check the deployment status of specific activity against an environment.\\r\\nThe activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsDeploymentStatus -ActivityId 123456789 -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -WaitForCompletion\\nThis will check the deployment status of specific activity against an environment.\\r\\nThe activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\r\\nThe cmdlet will every 300 seconds contact the LCS API endpoint and check if the status of the deployment is either success or failure.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsDeploymentStatus -ActivityId 123456789 -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -RetryTimeout \\\"00:01:00\\\"\\nThis will check the deployment status of specific activity against an environment, and allow for the cmdlet to retry for no more than 1 minute.\\r\\nThe activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\",\n        \"Syntax\":  \"Get-D365LcsDeploymentStatus [[-ProjectId] \\u003cInt32\\u003e] [[-BearerToken] \\u003cString\\u003e] [-ActivityId] \\u003cString\\u003e [-EnvironmentId] \\u003cString\\u003e [[-LcsApiUri] \\u003cString\\u003e] [-WaitForCompletion] [[-SleepInSeconds] \\u003cInt32\\u003e] [-FailOnErrorMessage] [[-RetryTimeout] \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365LcsEnvironmentHistory\",\n        \"Description\":  \"Get history details for a given environment from within a LCS project\\n\\nThere can be multiple pages of data, which requires you to use the TraverseAllPages parameter, if you want all data to be shown\",\n        \"Params\":  [\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiProjectId\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"Token\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiBearerToken\"\n                       ],\n                       [\n                           \"EnvironmentId\",\n                           \"Id of the environment that you want to be working against\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"TraverseAllPages\",\n                           \"Instruct the cmdlet to fetch all pages, until there isn\\u0027t more data available\\nThis can be a slow operation, as it has to call the LCS API multiple times, fetching a single page per call\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"FirstPages\",\n                           \"Instruct the cmdlet how many pages that you want it to retrieve from the LCS API\\nCan only be used in combination with -TraverseAllPages\\nThe default value is: 99 pages, which should be more than enough\\nPlease note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"99\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"FailOnErrorMessage\",\n                           \"Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\\r\\nThis allows you to implement custom retry / error handling logic\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"RetryTimeout\",\n                           \"The retry timeout, before the cmdlet should quit retrying based on the 429 status code\\nNeeds to be provided in the timspan notation:\\r\\n\\\"hh:mm:ss\\\"\\nhh is the number of hours, numerical notation only\\r\\nmm is the number of minutes\\r\\nss is the numbers of seconds\\nEach section of the timeout has to valid, e.g.\\r\\nhh can maximum be 23\\r\\nmm can maximum be 59\\r\\nss can maximum be 59\\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"00:00:00\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get history for a given environment within a LCS project\",\n        \"Name\":  \"Get-D365LcsEnvironmentHistory\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsEnvironmentHistory -ProjectId \\\"123456789\\\" -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\"\\nThis will list the first page of Environment History Data from the LCS API.\\r\\nThe LCS project is identified by the ProjectId \\\"123456789\\\", which can be obtained in the LCS portal.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\nA result set example:\\nName             : Service Update - 10.0.19\\r\\nType             : SFBinaryHotfix\\r\\nTypeDisplay      : Binary hotfix\\r\\nStartDateTimeUTC : 2021-07-11T00:01:57.423\\r\\nEndDateTimeUTC   : 2021-07-11T05:01:12.97\\r\\nStatus           : Completed\\r\\nActivityId       : e3509860-61d4-4003-9b45-6ea7d89aea30\\r\\nEnvironmentId    : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\r\\nProjectId        : 123456789\\nName             : Refresh database\\r\\nType             : SFSourceDbToSandbox\\r\\nTypeDisplay      : Refresh database\\r\\nStartDateTimeUTC : 2021-06-06T15:17:48.87\\r\\nEndDateTimeUTC   : 2021-06-06T16:33:40.367\\r\\nStatus           : Completed\\r\\nActivityId       : e3509860-61d4-4003-9b45-6ea7d89aea31\\r\\nEnvironmentId    : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\r\\nProjectId        : 123456789\\nName             : Export database\\r\\nType             : SFExportSandboxDb\\r\\nTypeDisplay      : Export database\\r\\nStartDateTimeUTC : 2021-04-27T22:08:01.103\\r\\nEndDateTimeUTC   : 2021-04-28T23:30:06.623\\r\\nStatus           : RollbackCompleted\\r\\nActivityId       : e3509860-61d4-4003-9b45-6ea7d89aea32\\r\\nEnvironmentId    : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\r\\nProjectId        : 123456789\\nName             : Main_2021.1.1.1\\r\\nType             : SFApplicationHotfix\\r\\nTypeDisplay      : Application deployable package\\r\\nStartDateTimeUTC : 2021-03-04T21:44:20.793\\r\\nEndDateTimeUTC   : 2021-03-04T22:48:17.303\\r\\nStatus           : Completed\\r\\nActivityId       : e3509860-61d4-4003-9b45-6ea7d89aea33\\r\\nEnvironmentId    : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\r\\nProjectId        : 123456789\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsEnvironmentHistory -ProjectId \\\"123456789\\\" -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -TraverseAllPages\\nThis will list the all the pages of Environment History Data from the LCS API.\\r\\nThe LCS project is identified by the ProjectId \\\"123456789\\\", which can be obtained in the LCS portal.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\r\\nThe cmdlet will TraverseAllPages from the LCS API.\\r\\nIt will use the default value for the maximum number of pages to return, 99 pages.\\nTraverseAllPages will increase the request time for completion, based on how many entries there is in the history.\\r\\nPlease be patient and let the system work for you.\\nPlease note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsEnvironmentHistory -ProjectId \\\"123456789\\\" -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -TraverseAllPages -FirstPages 2\\nThis will list the all the pages of Environment History Data from the LCS API.\\r\\nThe LCS project is identified by the ProjectId \\\"123456789\\\", which can be obtained in the LCS portal.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\r\\nThe cmdlet will TraverseAllPages from the LCS API.\\r\\nThe cmdlet will be fetching the FirstPages 2, to limit the output from the cmdlet to only the newest 2 pages.\\nTraverseAllPages will increase the request time for completion, based on how many entries there is in the history.\\r\\nPlease be patient and let the system work for you.\\nPlease note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\",\n        \"Syntax\":  \"Get-D365LcsEnvironmentHistory [-ProjectId \\u003cInt32\\u003e] [-BearerToken \\u003cString\\u003e] -EnvironmentId \\u003cString\\u003e [-LcsApiUri \\u003cString\\u003e] [-FailOnErrorMessage] [-RetryTimeout \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\\nGet-D365LcsEnvironmentHistory [-ProjectId \\u003cInt32\\u003e] [-BearerToken \\u003cString\\u003e] -EnvironmentId \\u003cString\\u003e [-TraverseAllPages] [-FirstPages \\u003cInt32\\u003e] [-LcsApiUri \\u003cString\\u003e] [-FailOnErrorMessage] [-RetryTimeout \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365LcsEnvironmentMetadata\",\n        \"Description\":  \"Get all meta data details for environments from within a LCS project\\n\\nIt supports listing all environments, but also supports single / specific environments by searching based on EnvironmentId or EnvironmentName\",\n        \"Params\":  [\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiProjectId\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"Token\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiBearerToken\"\n                       ],\n                       [\n                           \"EnvironmentId\",\n                           \"Id of the environment that you want to be working against\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"EnvironmentName\",\n                           \"Name of the environment that you want to be working against\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"TraverseAllPages\",\n                           \"Instruct the cmdlet to fetch all pages, until there isn\\u0027t more data available\\nThis can be a slow operation, as it has to call the LCS API multiple times, fetching a single page per call\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"FirstPages\",\n                           \"Instruct the cmdlet how many pages that you want it to retrieve from the LCS API\\nCan only be used in combination with -TraverseAllPages\\nThe default value is: 99 pages, which should be more than enough\\nPlease note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"99\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"FailOnErrorMessage\",\n                           \"Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\\r\\nThis allows you to implement custom retry / error handling logic\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"RetryTimeout\",\n                           \"The retry timeout, before the cmdlet should quit retrying based on the 429 status code\\nNeeds to be provided in the timspan notation:\\r\\n\\\"hh:mm:ss\\\"\\nhh is the number of hours, numerical notation only\\r\\nmm is the number of minutes\\r\\nss is the numbers of seconds\\nEach section of the timeout has to valid, e.g.\\r\\nhh can maximum be 23\\r\\nmm can maximum be 59\\r\\nss can maximum be 59\\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"00:00:00\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get LCS environment meta data from within a project\",\n        \"Name\":  \"Get-D365LcsEnvironmentMetadata\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsEnvironmentMetadata -ProjectId \\\"123456789\\\"\\nThis will show metadata for every available environment from the LCS project.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\nThe request time for completion is directly impacted by the number of environments within the LCS project.\\r\\nPlease be patient and let the system work for you.\\nYou might experience that not all environments are listed with this request, that would indicate that the LCS project has many environments. Please use the -TraverseAllPages parameter to ensure that \\r\\nall environments are outputted.\\nA result set example (Tier1):\\nEnvironmentId                  : c6566087-23bd-4561-8247-4d7f4efd3172\\r\\nEnvironmentName                : DevBox-01\\r\\nProjectId                      : 123456789\\r\\nEnvironmentInfrastructure      : CustomerManaged\\r\\nEnvironmentType                : DevTestDev\\r\\nEnvironmentGroup               : Primary\\r\\nEnvironmentProduct             : Finance and Operations\\r\\nEnvironmentEndpointBaseUrl     : https://devbox-4d7f4efd3172devaos.cloudax.dynamics.com/\\r\\nDeploymentState                : Stopped\\r\\nTopologyDisplayName            : Finance and Operations - Develop (10.0.18 with Platform update 42)\\r\\nCurrentApplicationBuildVersion : 10.0.793.41\\r\\nCurrentApplicationReleaseName  : 10.0.18\\r\\nCurrentPlatformReleaseName     : Update42\\r\\nCurrentPlatformVersion         : 7.0.5968.16999\\r\\nDeployedOnUTC                  : 7/5/2021 11:19 AM\\r\\nCloudStorageLocation           : West Europe\\r\\nDisasterRecoveryLocation       : North Europe\\r\\nDeploymentStatusDisplay        : Stopped\\r\\nCanStart                       : True\\r\\nCanStop                        : False\\nA result set example (Tier2+):\\nEnvironmentId                  : e7c53b85-8b6a-4ab9-8985-1e1ea89a0f0a\\r\\nEnvironmentName                : Contoso-SIT\\r\\nProjectId                      : 123456789\\r\\nEnvironmentInfrastructure      : SelfService\\r\\nEnvironmentType                : Sandbox\\r\\nEnvironmentGroup               : Primary\\r\\nEnvironmentProduct             : Finance and Operations\\r\\nEnvironmentEndpointBaseUrl     : https://Contoso-SIT.sandbox.operations.dynamics.com/\\r\\nDeploymentState                : Finished\\r\\nTopologyDisplayName            : AXHA\\r\\nCurrentApplicationBuildVersion : 10.0.761.10019\\r\\nCurrentApplicationReleaseName  : 10.0.17\\r\\nCurrentPlatformReleaseName     : PU41\\r\\nCurrentPlatformVersion         : 7.0.5934.35741\\r\\nDeployedOnUTC                  : 4/1/2020 9:35 PM\\r\\nCloudStorageLocation           : West Europe\\r\\nDisasterRecoveryLocation       :\\r\\nDeploymentStatusDisplay        : Deployed\\r\\nCanStart                       : False\\r\\nCanStop                        : False\\nA result set example (PROD):\\nEnvironmentId                  : a8aab4f4-d4f3-41f0-af80-54cea83b50d2\\r\\nEnvironmentName                : Contoso-PROD\\r\\nProjectId                      : 123456789\\r\\nEnvironmentInfrastructure      : SelfService\\r\\nEnvironmentType                : Production\\r\\nEnvironmentGroup               : Primary\\r\\nEnvironmentProduct             : Finance and Operations\\r\\nEnvironmentEndpointBaseUrl     : https://Contoso-PROD.operations.dynamics.com/\\r\\nDeploymentState                : Finished\\r\\nTopologyDisplayName            : AXHA\\r\\nCurrentApplicationBuildVersion : 10.0.886.48\\r\\nCurrentApplicationReleaseName  : 10.0.20\\r\\nCurrentPlatformReleaseName     : PU44\\r\\nCurrentPlatformVersion         : 7.0.6060.45\\r\\nDeployedOnUTC                  : 4/9/2020 12:11 PM\\r\\nCloudStorageLocation           : West Europe\\r\\nDisasterRecoveryLocation       :\\r\\nDeploymentStatusDisplay        : Deployed\\r\\nCanStart                       : False\\r\\nCanStop                        : False\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsEnvironmentMetadata -ProjectId \\\"123456789\\\" -TraverseAllPages\\nThis will show metadata for every available environment from the LCS project, across multiple pages.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nIt will use the default value for the maximum number of pages to return, 99 pages.\\nTraverseAllPages will increase the request time for completion, based on how many entries there is in the history.\\r\\nPlease be patient and let the system work for you.\\nPlease note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsEnvironmentMetadata -ProjectId \\\"123456789\\\" -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\"\\nThis will show metadata for every available environment from the LCS project.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsEnvironmentMetadata -ProjectId \\\"123456789\\\" -EnvironmentName \\\"Contoso-SIT\\\"\\nThis will show metadata for every available environment from the LCS project.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe environment is identified by the EnvironmentName \\\"Contoso-SIT\\\", which can be obtained in the LCS portal.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsEnvironmentMetadata -ProjectId \\\"123456789\\\" -TraverseAllPages -FirstPages 2\\nThis will show metadata for every available environment from the LCS project, across multiple pages.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nIt will use the default value for the maximum number of pages to return, 99 pages.\\r\\nThe cmdlet will be fetching the FirstPages 2, to limit the output from the cmdlet to only the newest 2 pages.\\nTraverseAllPages will increase the request time for completion, based on how many entries there is in the history.\\r\\nPlease be patient and let the system work for you.\\nPlease note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\",\n        \"Syntax\":  \"Get-D365LcsEnvironmentMetadata [-ProjectId \\u003cInt32\\u003e] [-BearerToken \\u003cString\\u003e] [-LcsApiUri \\u003cString\\u003e] [-FailOnErrorMessage] [-RetryTimeout \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\\nGet-D365LcsEnvironmentMetadata [-ProjectId \\u003cInt32\\u003e] [-BearerToken \\u003cString\\u003e] [-EnvironmentId \\u003cString\\u003e] [-LcsApiUri \\u003cString\\u003e] [-FailOnErrorMessage] [-RetryTimeout \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\\nGet-D365LcsEnvironmentMetadata [-ProjectId \\u003cInt32\\u003e] [-BearerToken \\u003cString\\u003e] [-EnvironmentName \\u003cString\\u003e] [-LcsApiUri \\u003cString\\u003e] [-FailOnErrorMessage] [-RetryTimeout \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\\nGet-D365LcsEnvironmentMetadata [-ProjectId \\u003cInt32\\u003e] [-BearerToken \\u003cString\\u003e] [-TraverseAllPages] [-FirstPages \\u003cInt32\\u003e] [-LcsApiUri \\u003cString\\u003e] [-FailOnErrorMessage] [-RetryTimeout \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365LcsEnvironmentRsatCertificate\",\n        \"Description\":  \"Download and persist the active rsat certificate from environments from within a LCS project\",\n        \"Params\":  [\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiProjectId\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"Token\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiBearerToken\"\n                       ],\n                       [\n                           \"EnvironmentId\",\n                           \"Id of the environment that you want to be working against\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the certificate files to be saved\\nThe default value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\RsatCert\\\\\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path $Script:DefaultTempPath \\\"RsatCert\\\")\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"FailOnErrorMessage\",\n                           \"Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\\r\\nThis allows you to implement custom retry / error handling logic\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"RetryTimeout\",\n                           \"The retry timeout, before the cmdlet should quit retrying based on the 429 status code\\nNeeds to be provided in the timspan notation:\\r\\n\\\"hh:mm:ss\\\"\\nhh is the number of hours, numerical notation only\\r\\nmm is the number of minutes\\r\\nss is the numbers of seconds\\nEach section of the timeout has to valid, e.g.\\r\\nhh can maximum be 23\\r\\nmm can maximum be 59\\r\\nss can maximum be 59\\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"00:00:00\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get LCS environment rsat certificate from within a project\",\n        \"Name\":  \"Get-D365LcsEnvironmentRsatCertificate\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsEnvironmentRsatCertificate -ProjectId \\\"123456789\\\" -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\"\\nThis will download the active rsat certificate file for the environment from the LCS project.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\nA result set example:\\nPath     : c:\\\\temp\\\\d365fo.tools\\\\RsatCert\\\\RSATCertificate_ABC-UAT_20240101-012030\\r\\nCerFile  : C:\\\\temp\\\\d365fo.tools\\\\RsatCert\\\\RSATCertificate_ABC-UAT_20240101-012030\\\\RSATCertificate_ABC-UAT_20240101-012030.cer\\r\\nPfxFile  : C:\\\\temp\\\\d365fo.tools\\\\RsatCert\\\\RSATCertificate_ABC-UAT_20240101-012030\\\\RSATCertificate_ABC-UAT_20240101-012030.pfx\\r\\nFileName : RSATCertificate_ABC-UAT_20240101-012030.zip\\r\\nPassword : 9zbPiLMTk676mkq5FvqQ\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsEnvironmentRsatCertificate -ProjectId \\\"123456789\\\" -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" | Import-D365RsatSelfServiceCertificates\\nThis will download the active rsat certificate file for the environment from the LCS project.\\r\\nThe resulting files are then imported into the certificate store on the local machine.\",\n        \"Syntax\":  \"Get-D365LcsEnvironmentRsatCertificate [[-ProjectId] \\u003cInt32\\u003e] [[-BearerToken] \\u003cString\\u003e] [-EnvironmentId] \\u003cString\\u003e [[-OutputPath] \\u003cString\\u003e] [[-LcsApiUri] \\u003cString\\u003e] [-FailOnErrorMessage] [[-RetryTimeout] \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365LcsSharedAssetFile\",\n        \"Description\":  \"Get the information for the file assets from the shared asset library of LCS matching the search criteria\",\n        \"Params\":  [\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\\nDefault value can be configured using Set-D365LcsApiConfig\\nAlthough the assets are stored in the shared asset library, their information is retrieved in context of a project to get the full information.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiProjectId\"\n                       ],\n                       [\n                           \"FileType\",\n                           \"Type of file you want to list from the LCS Asset Library\\nValid options:\\r\\n\\\"Model\\\"\\r\\n\\\"Process Data Package\\\"\\r\\n\\\"Software Deployable Package\\\"\\r\\n\\\"GER Configuration\\\"\\r\\n\\\"Data Package\\\"\\r\\n\\\"PowerBI Report Model\\\"\\r\\n\\\"E-Commerce Package\\\"\\r\\n\\\"NuGet Package\\\"\\r\\n\\\"Retail Self-Service Package\\\"\\r\\n\\\"Commerce Cloud Scale Unit Extension\\\"\\nDefault value is \\\"Software Deployable Package\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"SoftwareDeployablePackage\"\n                       ],\n                       [\n                           \"AssetName\",\n                           \"Name of the asset that you are looking for\\nAccepts wildcards for searching. E.g. -AssetName \\\"*ISV*\\\"\\nDefault value is \\\"*\\\" which will search for all assets via the Name property\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"AssetVersion\",\n                           \"Version of the Asset file that you are looking for\\nIt does a simple compare against the response from LCS and only lists the ones that matches\\nAccepts wildcards for searching. E.g. -AssetVersion \\\"*ISV*\\\"\\nDefault value is \\\"*\\\" which will search for all files\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"AssetFilename\",\n                           \"Name of the file that you are looking for\\nAccepts wildcards for searching. E.g. -AssetFilename \\\"*ISV*\\\"\\nDefault value is \\\"*\\\" which will search for all files via the FileName property\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"AssetDescription\",\n                           \"Name of the file that you are looking for\\nAccepts wildcards for searching. E.g. -AssetDescription \\\"*ISV*\\\"\\nDefault value is \\\"*\\\" which will search for all files via the FileDescription property\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"AssetId\",\n                           \"Id of the file that you are looking for\\nAccepts wildcards for searching. E.g. -AssetId \\\"*ISV*\\\"\\nDefault value is \\\"*\\\" which will search for all files via the AssetId property\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"Token\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiBearerToken\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"Latest\",\n                           \"Instruct the cmdlet to only fetch the latest file from the Asset Library from LCS\",\n                           \"GetLatest\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"SkipSasGeneration\",\n                           \"Instruct the cmdlet to only fetch the meta data from the asset file (entry)\\nThis is to speed up the listing of entries, in some of the larger areas in the Shared Asset Library\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"RetryTimeout\",\n                           \"The retry timeout, before the cmdlet should quit retrying based on the 429 status code\\nNeeds to be provided in the timspan notation:\\r\\n\\\"hh:mm:ss\\\"\\nhh is the number of hours, numerical notation only\\r\\nmm is the number of minutes\\r\\nss is the numbers of seconds\\nEach section of the timeout has to valid, e.g.\\r\\nhh can maximum be 23\\r\\nmm can maximum be 59\\r\\nss can maximum be 59\\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"00:00:00\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\\r\\nUsually this parameter is not used directly, but via the Enable-D365Exception cmdlet\\r\\nSee https://github.com/d365collaborative/d365fo.tools/wiki/Exception-handling#what-does-the--enableexception-parameter-do for further information\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Florian Hopfner (@FH-Inway)\",\n        \"Synopsis\":  \"Get information for assets from the shared asset library of LCS\",\n        \"Name\":  \"Get-D365LcsSharedAssetFile\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsSharedAssetFile -ProjectId 123456789 -FileType SoftwareDeployablePackage -BearerToken \\\"JldjfafLJdfjlfsalfd...\\\" -LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\"\\nThis will list all Software Deployable Packages in the shared asset library.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe request will authenticate with the BearerToken \\\"JldjfafLJdfjlfsalfd...\\\".\\r\\nThe http request will be going to the LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\" (NON-EUROPE).\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage\\nThis will list all Software Deployable Packages in the shared asset library.\\r\\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetFilename \\\"*MAIN*\\\"\\nThis will list all Software Deployable Packages in the shared asset library that match the \\\"*MAIN*\\\" search pattern in the file name of the asset.\\r\\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\\r\\nIt will filter the output to match the AssetFilename \\\"*MAIN*\\\" search pattern.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetName \\\"*MAIN*\\\"\\nThis will list all Software Deployable Packages in the shared asset library that match the \\\"*MAIN*\\\" search pattern in the name of the asset.\\r\\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\\r\\nIt will filter the output to match the AssetName \\\"*MAIN*\\\" search pattern.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetDescription \\\"*TEST*\\\"\\nThis will list all Software Deployable Packages in the shared asset library that match the \\\"*TEST*\\\" search pattern in the asset description.\\r\\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\\r\\nIt will filter the output to match the AssetDescription \\\"*TEST*\\\" search pattern.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 6 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetId \\\"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\\\"\\nThis will list all Software Deployable Packages in the shared asset library that match the \\\"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\\\" search pattern in the asset id.\\r\\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\\r\\nIt will filter the output to match the AssetId \\\"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\\\" search pattern.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 7 --------------------------\\nPS C:\\\\\\u003e$asset = Get-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage -Latest\\nPS C:\\\\\\u003e Invoke-D365AzCopyTransfer -SourceUri $asset.FileLocation -DestinationUri C:\\\\Temp\\\\d365fo.tools\\\\$($asset.Filename) -ShowOriginalProgress\\nThis will download the latest Software Deployable Package from the shared asset library in LCS onto your local machine.\\r\\nIt will list Software Deployable Packages based on the FileType parameter.\\r\\nIt will list the latest (newest) Software Deployable Package.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 8 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage -RetryTimeout \\\"00:01:00\\\"\\nThis will list all Software Deployable Packages in the shared asset library and allow for the cmdlet to retry for no more than 1 minute.\\r\\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 9 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage -SkipSasGeneration\\nThis will list all Software Deployable Packages in the shared asset library, but skip the SAS / Download generation\\r\\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\\nThis will increase the speed getting the list of assets - but you will not get a downloadable link.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\",\n        \"Syntax\":  \"Get-D365LcsSharedAssetFile [[-ProjectId] \\u003cInt32\\u003e] [[-FileType] {Model | ProcessDataPackage | SoftwareDeployablePackage | GERConfiguration | DataPackage | PowerBIReportModel | ECommercePackage | NuGetPackage | RetailSelfServicePackage | CommerceCloudScaleUnitExtension}] [[-AssetName] \\u003cString\\u003e] [[-AssetVersion] \\u003cString\\u003e] [[-AssetFilename] \\u003cString\\u003e] [[-AssetDescription] \\u003cString\\u003e] [[-AssetId] \\u003cString\\u003e] [[-BearerToken] \\u003cString\\u003e] [[-LcsApiUri] \\u003cString\\u003e] [-Latest] [-SkipSasGeneration] [[-RetryTimeout] \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365MaintenanceMode\",\n        \"Description\":  \"Get the maintenance mode status of the Dynamics 365 environment to make sure that things are in the correct state\",\n        \"Tags\":  [\n                     \"MaintenanceMode\",\n                     \"Maintenance\",\n                     \"License\",\n                     \"Configuration\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@splaxi)\",\n        \"Synopsis\":  \"Get the maintenance mode status of the environment\",\n        \"Name\":  \"Get-D365MaintenanceMode\",\n        \"Links\":  [\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365MaintenanceMode\\nThis will get the current state of the maintenance mode of the environment\",\n        \"Syntax\":  \"Get-D365MaintenanceMode [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365Model\",\n        \"Description\":  \"Get available model from the machine running the AOS service for Dynamics 365 Finance \\u0026 Operations\",\n        \"Tags\":  [\n                     \"PackagesLocalDirectory\",\n                     \"Servicing\",\n                     \"Model\",\n                     \"Models\",\n                     \"Module\",\n                     \"Modules\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"Name of the model that you are looking for\\nAccepts wildcards for searching. E.g. -Name \\\"Application*Adaptor\\\"\\nDefault value is \\\"*\\\" which will search for all models\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"Module\",\n                           \"Name of the module that you want to list models from\\nAccepts wildcards for searchinf. E.g. -Module \\\"Application*Adaptor\\\"\\nDefault value is \\\"*\\\" which will search across all modules\",\n                           \"ModuleName\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"*\"\n                       ],\n                       [\n                           \"CustomizableOnly\",\n                           \"Instructs the cmdlet to filter out all models that cannot be customized\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"ExcludeMicrosoftModels\",\n                           \"Instructs the cmdlet to exclude all models that has Microsoft as the publisher from the output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"ExcludeBinaryModels\",\n                           \"Instruct the cmdlet to exclude binary models from the output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the AOS service PackagesLocalDirectory\\\\bin\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nDefault path is the same as the AOS service \\\"PackagesLocalDirectory\\\" directory\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get available model from Dynamics 365 Finance \\u0026 Operations environment\",\n        \"Name\":  \"Get-D365Model\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365Model\\nShows the entire list of installed models located in the default location on the machine.\\nA result set example:\\nModelName                      Module                         IsBinary Customization        Id Publisher\\r\\n---------                      ------                         -------- -------------        -- ---------\\r\\nAccountsPayableMobile          AccountsPayableMobile          False    DoNotAllow    895571380 Microsoft Corporation\\r\\nApplicationCommon              ApplicationCommon              False    DoNotAllow      8956718 Microsoft\\r\\nApplicationFoundation          ApplicationFoundation          False    Allow               450 Microsoft Corporation\\r\\nIsvFoundation                  IsvFoundation                  True     Allow         895972027 Isv Corp\\r\\nIsvLicense                     IsvLicense                     True     DoNotAllow    895972028 Isv Corp\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365Model -CustomizableOnly\\nShows only the models that are marked as customizable.\\r\\nWill only include models that is Customization = \\\"Allow\\\".\\nA result set example:\\nModelName                      Module                         IsBinary Customization        Id Publisher\\r\\n---------                      ------                         -------- -------------        -- ---------\\r\\nApplicationFoundation          ApplicationFoundation          False    Allow               450 Microsoft Corporation\\r\\nApplicationPlatform            ApplicationPlatform            False    Allow               400 Microsoft Corporation\\r\\nApplicationPlatformFormAdaptor ApplicationPlatformFormAdaptor False    Allow            855030 Microsoft Corporation\\r\\nIsvFoundation                  IsvFoundation                  True     Allow         895972027 Isv Corp\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365Model -ExcludeMicrosoftModels\\nShows only the models that doesn\\u0027t have \\\"Microsoft\\\" in the publisher.\\r\\nWill only include models that is Publisher -NotLike \\\"Microsoft*\\\".\\nA result set example:\\nModelName                      Module                         IsBinary Customization        Id Publisher\\r\\n---------                      ------                         -------- -------------        -- ---------\\r\\nIsvFoundation                  IsvFoundation                  True     Allow         895972027 Isv Corp\\r\\nIsvLicense                     IsvLicense                     True     DoNotAllow    895972028 Isv Corp\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365Model -ExcludeBinaryModels\\nShows only the models that are NOT binary.\\r\\nWill only include models that is IsBinary = \\\"False\\\".\\nA result set example:\\nModelName                      Module                         IsBinary Customization        Id Publisher\\r\\n---------                      ------                         -------- -------------        -- ---------\\r\\nAccountsPayableMobile          AccountsPayableMobile          False    DoNotAllow    895571380 Microsoft Corporation\\r\\nApplicationCommon              ApplicationCommon              False    DoNotAllow      8956718 Microsoft\\r\\nApplicationFoundation          ApplicationFoundation          False    Allow               450 Microsoft Corporation\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eGet-D365Model -CustomizableOnly -ExcludeMicrosoftModels\\nShows only the models that are marked as customizable and NOT from Microsoft.\\r\\nWill only include models that is Customization = \\\"Allow\\\".\\r\\nWill only include models that is Publisher -NotLike \\\"Microsoft*\\\".\\nA result set example:\\nModelName                      Module                         IsBinary Customization        Id Publisher\\r\\n---------                      ------                         -------- -------------        -- ---------\\r\\nIsvFoundation                  IsvFoundation                  True     Allow         895972027 Isv Corp\\n-------------------------- EXAMPLE 6 --------------------------\\nPS C:\\\\\\u003eGet-D365Model -Name \\\"Application*Adaptor\\\"\\nShows the list of models where the name fits the search \\\"Application*Adaptor\\\".\\nA result set example:\\nModelName                      Module                         IsBinary Customization        Id Publisher\\r\\n---------                      ------                         -------- -------------        -- ---------\\r\\nApplicationFoundationFormAd... ApplicationFoundationFormAd... False    DoNotAllow       855029 Microsoft Corporation\\r\\nApplicationPlatformFormAdaptor ApplicationPlatformFormAdaptor False    Allow            855030 Microsoft Corporation\\r\\nApplicationSuiteFormAdaptor    ApplicationSuiteFormAdaptor    False    DoNotAllow       855028 Microsoft Corporation\\r\\nApplicationWorkspacesFormAd... ApplicationWorkspacesFormAd... False    DoNotAllow       855066 Microsoft Corporation\\n-------------------------- EXAMPLE 7 --------------------------\\nPS C:\\\\\\u003eGet-D365Model -Module ApplicationSuite\\nShows only the models that are inside the ApplicationSuite module.\\nA result set example:\\nModelName                      Module                         IsBinary Customization        Id Publisher\\r\\n---------                      ------                         -------- -------------        -- ---------\\r\\nElectronic Reporting Applic... ApplicationSuite               False    DoNotAllow       855009 Microsoft Corporation\\r\\nFoundation                     ApplicationSuite               False    DoNotAllow           17 Microsoft Corporation\\r\\nSCMControls                    ApplicationSuite               False    DoNotAllow       855891 Microsoft Corporation\\r\\nTax Books Application Suite... ApplicationSuite               False    DoNotAllow    895570102 Microsoft Corporation\\r\\nTax Engine Application Suit... ApplicationSuite               False    DoNotAllow      8957001 Microsoft Corporation\\n-------------------------- EXAMPLE 8 --------------------------\\nPS C:\\\\\\u003eGet-D365Model -Name \\\"*Application*\\\" -Module \\\"*Suite*\\\"\\nShows the list of models where the name fits the search \\\"*Application*\\\" and the module name fits the search \\\"*Suite*\\\".\\nA result set example:\\nModelName                      Module                         IsBinary Customization        Id Publisher\\r\\n---------                      ------                         -------- -------------        -- ---------\\r\\nApplicationSuiteFormAdaptor    ApplicationSuiteFormAdaptor    False    DoNotAllow       855028 Microsoft Corporation\\r\\nAtlApplicationSuite            AtlApplicationSuite            False    DoNotAllow    895972466 Microsoft Corporation\\r\\nElectronic Reporting Applic... ApplicationSuite               False    DoNotAllow       855009 Microsoft Corporation\\r\\nTax Books Application Suite... ApplicationSuite               False    DoNotAllow    895570102 Microsoft Corporation\\r\\nTax Engine Application Suit... ApplicationSuite               False    DoNotAllow      8957001 Microsoft Corporation\",\n        \"Syntax\":  \"Get-D365Model [[-Name] \\u003cString\\u003e] [[-Module] \\u003cString\\u003e] [-CustomizableOnly] [-ExcludeMicrosoftModels] [-ExcludeBinaryModels] [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365Module\",\n        \"Description\":  \"Get installed package / module from the machine running the AOS service for Dynamics 365 Finance \\u0026 Operations\",\n        \"Tags\":  [\n                     \"PackagesLocalDirectory\",\n                     \"Servicing\",\n                     \"Model\",\n                     \"Models\",\n                     \"Package\",\n                     \"Packages\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"Name of the package / module that you are looking for\\nAccepts wildcards for searching. E.g. -Name \\\"Application*Adaptor\\\"\\nDefault value is \\\"*\\\" which will search for all packages / modules\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"ExcludeBinaryModules\",\n                           \"Instruct the cmdlet to exclude binary modules from the output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"InDependencyOrder\",\n                           \"Instructs the cmdlet to return modules in dependency order, starting with modules\\r\\nwith no references to other modules.\",\n                           \"Dependency\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the AOS service PackagesLocalDirectory\\\\bin\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get installed package / module from Dynamics 365 Finance \\u0026 Operations environment\",\n        \"Name\":  \"Get-D365Module\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365Module\\nShows the entire list of installed packages / modules located in the default location on the machine.\\nA result set example:\\nModuleName                               IsBinary Version         References\\r\\n----------                               -------- -------         ----------\\r\\nAccountsPayableMobile                    False    10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli...\\r\\nApplicationCommon                        False    10.0.8008.26462 {ApplicationFoundation, ApplicationPlatform}\\r\\nApplicationFoundation                    False    7.0.5493.35504  {ApplicationPlatform}\\r\\nApplicationFoundationFormAdaptor         False    7.0.4841.35227  {ApplicationPlatform, ApplicationFoundation, TestE...\\r\\nCustom                                   True     10.0.0.0        {ApplicationPlatform}\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365Module -ExcludeBinaryModules\\nOutputs the all packages / modules that are NOT binary.\\r\\nWill only include modules that is IsBinary = \\\"False\\\".\\nA result set example:\\nModuleName                               IsBinary Version         References\\r\\n----------                               -------- -------         ----------\\r\\nAccountsPayableMobile                    False    10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli...\\r\\nApplicationCommon                        False    10.0.8008.26462 {ApplicationFoundation, ApplicationPlatform}\\r\\nApplicationFoundation                    False    7.0.5493.35504  {ApplicationPlatform}\\r\\nApplicationFoundationFormAdaptor         False    7.0.4841.35227  {ApplicationPlatform, ApplicationFoundation, TestE...\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365Module -InDependencyOrder\\nReturn packages / modules in dependency order, starting with modules with no references to other modules.\\nA result set example:\\nModuleName                               IsBinary Version         References\\r\\n----------                               -------- -------         ----------\\r\\nApplicationPlatform                      False    7.0.0.0         {}\\r\\nApplicationFoundation                    False    7.0.0.0         {ApplicationPlatform}\\r\\nApplicationCommon                        False    10.21.36.8818   {ApplicationFoundation, ApplicationPlatform}\\r\\nAppTroubleshootingCore                   False    10.21.1136.2... {ApplicationCommon, ApplicationFoundation, Applica...\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365Module -Name \\\"Application*Adaptor\\\"\\nShows the list of installed packages / modules where the name fits the search \\\"Application*Adaptor\\\".\\nA result set example:\\nModuleName                               IsBinary Version         References\\r\\n----------                               -------- -------         ----------\\r\\nApplicationFoundationFormAdaptor         False    7.0.4841.35227  {ApplicationPlatform, ApplicationFoundation, TestE...\\r\\nApplicationPlatformFormAdaptor           False    7.0.4841.35227  {ApplicationPlatform, TestEssentials}\\r\\nApplicationSuiteFormAdaptor              False    10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli...\\r\\nApplicationWorkspacesFormAdaptor         False    10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli...\",\n        \"Syntax\":  \"Get-D365Module [[-Name] \\u003cString\\u003e] [-ExcludeBinaryModules] [-InDependencyOrder] [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365OfflineAuthenticationAdminEmail\",\n        \"Description\":  \"Get the registered offline administrator from the \\\"DynamicsDevConfig.xml\\\" file located in the default Package Directory\",\n        \"Tags\":  [\n                     \"Development\",\n                     \"Email\",\n                     \"DynamicsDevConfig\",\n                     \"Offline\",\n                     \"Authentication\"\n                 ],\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Synopsis\":  \"Gets the registered offline administrator e-mail configured\",\n        \"Name\":  \"Get-D365OfflineAuthenticationAdminEmail\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365OfflineAuthenticationAdminEmail\\nWill read the DynamicsDevConfig.xml and display the registered Offline Administrator E-mail address.\",\n        \"Syntax\":  \"Get-D365OfflineAuthenticationAdminEmail [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365PackageBundleDetail\",\n        \"Description\":  \"Get the details from an axscdppkg file by extracting it like a zip file.\\n\\nCapable of extracting the manifest details from the inner packages as well\",\n        \"Tags\":  [\n                     \"Hotfix\",\n                     \"KB\",\n                     \"Manifest\",\n                     \"HotfixPackageBundle\",\n                     \"axscdppkg\",\n                     \"Package\",\n                     \"Bundle\",\n                     \"Deployable\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the axscdppkg file you want to analyze\",\n                           \"File\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ExtractionPath\",\n                           \"Path where you want the cmdlet to work with extraction of all the files\\nDefault value is: C:\\\\Users\\\\Username\\\\AppData\\\\Local\\\\Temp\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"([System.IO.Path]::GetTempPath())\"\n                       ],\n                       [\n                           \"KB\",\n                           \"KB number of the hotfix that you are looking for\\nAccepts wildcards for searching. E.g. -KB \\\"4045*\\\"\\nDefault value is \\\"*\\\" which will search for all KB\\u0027s\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"Hotfix\",\n                           \"Package Id / Hotfix number the hotfix that you are looking for\\nAccepts wildcards for searching. E.g. -Hotfix \\\"7045*\\\"\\nDefault value is \\\"*\\\" which will search for all hotfixes\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"Traverse\",\n                           \"Switch to instruct the cmdlet to traverse the inner packages and extract their details\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"KeepFiles\",\n                           \"Switch to instruct the cmdlet to keep the files for further manual analyze\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"IncludeRawManifest\",\n                           \"Switch to instruct the cmdlet to include the raw content of the manifest file\\nOnly works with the -Traverse option\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the details from an axscdppkg file\",\n        \"Name\":  \"Get-D365PackageBundleDetail\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365PackageBundleDetail -Path \\\"c:\\\\temp\\\\HotfixPackageBundle.axscdppkg\\\" -Traverse\\nThis will extract all the content from the \\\"HotfixPackageBundle.axscdppkg\\\" file and extract all inner packages. For each inner package it will find the manifest file and fetch the KB numbers. The raw \\r\\nmanifest file content is included to be analyzed.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365PackageBundleDetail -Path \\\"c:\\\\temp\\\\HotfixPackageBundle.axscdppkg\\\" -ExtractionPath C:\\\\Temp\\\\20180905 -Traverse -KeepFiles\\nThis will extract all the content from the \\\"HotfixPackageBundle.axscdppkg\\\" file and extract all inner packages. It will extract the content into C:\\\\Temp\\\\20180905 and keep the files after completion.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365PackageBundleDetail -Path C:\\\\temp\\\\HotfixPackageBundle.axscdppkg -Traverse -IncludeRawManifest\\nThis is an advanced scenario.\\nThis will traverse the \\\"HotfixPackageBundle.axscdppkg\\\" file and will include the raw manifest file details in the output.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365PackageBundleDetail -Path C:\\\\temp\\\\HotfixPackageBundle.axscdppkg -Traverse -IncludeRawManifest | ForEach-Object {$_.RawManifest | Out-File \\\"C:\\\\temp\\\\$($_.PackageId).txt\\\"}\\nThis is an advanced scenario.\\nThis will traverse the \\\"HotfixPackageBundle.axscdppkg\\\" file and save the manifest files into c:\\\\temp. Everything else is omitted and cleaned up.\",\n        \"Syntax\":  \"Get-D365PackageBundleDetail [-Path] \\u003cString\\u003e [[-ExtractionPath] \\u003cString\\u003e] [[-KB] \\u003cString\\u003e] [[-Hotfix] \\u003cString\\u003e] [-Traverse] [-KeepFiles] [-IncludeRawManifest] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365PackageLabelResourceFile\",\n        \"Description\":  \"Get label (resource) file from the package directory of a Dynamics 365 Finance \\u0026 Operations environment\",\n        \"Tags\":  [\n                     \"PackagesLocalDirectory\",\n                     \"Label\",\n                     \"Labels\",\n                     \"Language\",\n                     \"Development\",\n                     \"Servicing\",\n                     \"Module\",\n                     \"Package\",\n                     \"Packages\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed packages\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"Path\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"Name\",\n                           \"Name of the label (resource) file you are looking for\\nAccepts wildcards for searching. E.g. -Name \\\"Fixed*Accounting\\\"\\nDefault value is \\\"*\\\" which will search for all label files\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"Language\",\n                           \"The language of the label file you are looking for\\nAccepts wildcards for searching. E.g. -Language \\\"en*\\\"\\nDefault value is \\\"en-US\\\" which will search for en-US language files\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"en-US\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get label / resource file from a package\",\n        \"Name\":  \"Get-D365PackageLabelResourceFile\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365PackageLabelResourceFile -PackageDirectory \\\"C:\\\\AOSService\\\\PackagesLocalDirectory\\\\ApplicationSuite\\\"\\nShows all the label files for ApplicationSuite package\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365PackageLabelResourceFile -PackageDirectory \\\"C:\\\\AOSService\\\\PackagesLocalDirectory\\\\ApplicationSuite\\\" -Name \\\"Fixed*Accounting\\\"\\nShows the label files for ApplicationSuite package where the name fits the search \\\"Fixed*Accounting\\\"\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365InstalledPackage -Name \\\"ApplicationSuite\\\" | Get-D365PackageLabelResourceFile\\nShows all label files (en-US) for the ApplicationSuite package\",\n        \"Syntax\":  \"Get-D365PackageLabelResourceFile -PackageDirectory \\u003cString\\u003e [-Name \\u003cString\\u003e] [-Language \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\\nGet-D365PackageLabelResourceFile -PackageDirectory \\u003cString\\u003e [-Name \\u003cString\\u003e] [-Language \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365PackageLabelResources\",\n        \"Description\":  \"Get label details from the resource file for a Dynamics 365 Finance \\u0026 Operations environment\",\n        \"Tags\":  [\n                     \"PackagesLocalDirectory\",\n                     \"Label\",\n                     \"Labels\",\n                     \"Language\",\n                     \"Development\",\n                     \"Servicing\",\n                     \"Resource\",\n                     \"Resources\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"FilePath\",\n                           \"The path to resource file that you want to get label details from\",\n                           \"Path\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"Name\",\n                           \"Name of the label you are looking for\\nAccepts wildcards for searching. E.g. -Name \\\"@PRO*\\\"\\nDefault value is \\\"*\\\" which will search for all labels in the resource file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"Value\",\n                           \"Value of the label you are looking for\\nAccepts wildcards for searching. E.g. -Name \\\"*Qty*\\\"\\nDefault value is \\\"*\\\" which will search for all values in the resource file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"IncludePath\",\n                           \"Switch to indicate whether you want the result set to include the path to the resource file or not\\nDefault is OFF - path details will not be part of the output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get label from the resource file\",\n        \"Name\":  \"Get-D365PackageLabelResources\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365PackageLabelResources -Path \\\"C:\\\\AOSService\\\\PackagesLocalDirectory\\\\ApplicationSuite\\\\Resources\\\\en-US\\\\PRO.resources.dll\\\"\\nWill get all labels from the \\\"PRO.resouce.dll\\\" file\\nThe language is determined by the path to the resource file and nothing else\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365PackageLabelResources -Path \\\"C:\\\\AOSService\\\\PackagesLocalDirectory\\\\ApplicationSuite\\\\Resources\\\\en-US\\\\PRO.resources.dll\\\" -Name \\\"@PRO505\\\"\\nWill get the label with the name \\\"@PRO505\\\" from the \\\"PRO.resouce.dll\\\" file\\nThe language is determined by the path to the resource file and nothing else\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365PackageLabelResources -Path \\\"C:\\\\AOSService\\\\PackagesLocalDirectory\\\\ApplicationSuite\\\\Resources\\\\en-US\\\\PRO.resources.dll\\\" -Value \\\"*qty*\\\"\\nWill get all the labels where the value fits the search \\\"*qty*\\\" from the \\\"PRO.resouce.dll\\\" file\\nThe language is determined by the path to the resource file and nothing else\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365InstalledPackage -Name \\\"ApplicationSuite\\\" | Get-D365PackageLabelResourceFile -Language \\\"da\\\" | Get-D365PackageLabelResources -value \\\"*batch*\\\" -IncludePath\\nWill get all the labels, across all label files, for the \\\"ApplicationSuite\\\", where the language is \\\"da\\\" and where the label value fits the search \\\"*batch*\\\".\\nThe path to the label file is included in the output.\",\n        \"Syntax\":  \"Get-D365PackageLabelResources -FilePath \\u003cString\\u003e [-Name \\u003cString\\u003e] [-Value \\u003cString\\u003e] [-IncludePath] [\\u003cCommonParameters\\u003e]\\nGet-D365PackageLabelResources -FilePath \\u003cString\\u003e [-Name \\u003cString\\u003e] [-Value \\u003cString\\u003e] [-IncludePath] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365ProductInformation\",\n        \"Description\":  \"Gets detailed information about application and platform\",\n        \"Tags\":  [\n                     \"Build\",\n                     \"Version\",\n                     \"Reference\",\n                     \"ProductVersion\",\n                     \"ProductDetails\",\n                     \"Product\"\n                 ],\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Rasmus Andersen (@ITRasmus)\",\n        \"Synopsis\":  \"Returns information about D365FO\",\n        \"Name\":  \"Get-D365ProductInformation\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365ProductInformation\\nThis will get product, platform and application version details for the environment\",\n        \"Syntax\":  \"Get-D365ProductInformation [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365RsatCertificateThumbprint\",\n        \"Description\":  \"Locate the thumbprint for the certificate created during the RSAT installation\",\n        \"Tags\":  [\n                     \"RSAT\",\n                     \"Certificate\",\n                     \"Testing\",\n                     \"Regression Suite Automation Test\",\n                     \"Regression\",\n                     \"Test\",\n                     \"Automation.\"\n                 ],\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the thumbprint from the RSAT certificate\",\n        \"Name\":  \"Get-D365RsatCertificateThumbprint\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365RsatCertificateThumbprint\\nThis will locate any certificates that has 127.0.0.1 in its name.\\r\\nIt will show the subject and the thumbprint values.\",\n        \"Syntax\":  \"Get-D365RsatCertificateThumbprint [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365RsatPlaybackFile\",\n        \"Description\":  \"Get all the RSAT playback files from the last executions\",\n        \"Tags\":  [\n                     \"RSAT\",\n                     \"Testing\",\n                     \"Regression Suite Automation Test\",\n                     \"Regression\",\n                     \"Test\",\n                     \"Automation\",\n                     \"Playback\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"The path where the RSAT tool will be writing the files\\nThe default path is:\\r\\n\\\"C:\\\\Users\\\\USERNAME\\\\AppData\\\\Roaming\\\\regressionTool\\\\playback\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:RsatplaybackPath\"\n                       ],\n                       [\n                           \"Name\",\n                           \"Name of Test Case that you are looking for\\nDefault value is \\\"*\\\" which will search for all Test Cases and their corresponding files\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"ExecutionUsername\",\n                           \"Name of the user account has been running the RSAT tests on a machine that isn\\u0027t the same as the current user\\nWill enable you to log on to RSAT server that is running the tests from a console, automated, and is other account than the current user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the RSAT playback files\",\n        \"Name\":  \"Get-D365RsatPlaybackFile\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365RsatPlaybackFile\\nThis will get all the RSAT playback files.\\r\\nIt will search for the files in the current user AppData system folder.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365RsatPlaybackFile -Name *4080*\\nThis will get all the RSAT playback files which has \\\"4080\\\" as part of its name.\\r\\nIt will search for the files in the current user AppData system folder.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365RsatPlaybackFile -ExecutionUsername RSAT-ServiceAccount\\nThis will get all the RSAT playback files that were executed by the RSAT-ServiceAccount user.\\r\\nIt will search for the files in the RSAT-ServiceAccount user AppData system folder.\",\n        \"Syntax\":  \"Get-D365RsatPlaybackFile [-Path \\u003cString\\u003e] [-Name \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\\nGet-D365RsatPlaybackFile [-Name \\u003cString\\u003e] [-ExecutionUsername \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365RsatSoapHostname\",\n        \"Description\":  \"Get the SOAP hostname from the IIS configuration, to be used during the Rsat configuration\",\n        \"Tags\":  [\n                     \"RSAT\",\n                     \"Testing\",\n                     \"Regression Suite Automation Test\",\n                     \"Regression\",\n                     \"Test\",\n                     \"Automation\",\n                     \"SOAP\"\n                 ],\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the SOAP hostname for the D365FO environment\",\n        \"Name\":  \"Get-D365RsatSoapHostname\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365RsatSoapHostname\\nThis will get the SOAP hostname from IIS.\\r\\nIt will display the SOAP URL / URI correctly formatted, to be used during the configuration of Rsat.\",\n        \"Syntax\":  \"Get-D365RsatSoapHostname [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365Runbook\",\n        \"Description\":  \"Get the full path and filename of a Dynamics 365 Runbook\",\n        \"Tags\":  [\n                     \"Runbook\",\n                     \"Servicing\",\n                     \"Hotfix\",\n                     \"DeployablePackage\",\n                     \"Deployable Package\",\n                     \"InstallationRecordsDirectory\",\n                     \"Installation Records Directory\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the folder containing the runbook files\\nThe default path is \\\"InstallationRecord\\\" which is normally located on the \\\"C:\\\\DynamicsAX\\\\InstallationRecords\\\"\",\n                           \"\",\n                           false,\n                           \"true (ByValue, ByPropertyName)\",\n                           \"(Join-Path $Script:InstallationRecordsDir \\\"Runbooks\\\")\"\n                       ],\n                       [\n                           \"Name\",\n                           \"Name of the runbook file that you are looking for\\nThe parameter accepts wildcards. E.g. -Name *hotfix-20181024*\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"Latest\",\n                           \"Instruct the cmdlet to only get the latest runbook file, based on the last written attribute\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get a Dynamics 365 Runbook\",\n        \"Name\":  \"Get-D365Runbook\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365Runbook\\nThis will list all runbooks that are available in the default location.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365Runbook -Latest\\nThis will get the latest runbook file from the default InstallationRecords directory on the machine.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365Runbook -Latest | Invoke-D365RunbookAnalyzer\\nThis will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365Runbook -Latest | Invoke-D365RunbookAnalyzer | Out-File \\\"C:\\\\Temp\\\\d365fo.tools\\\\runbook-analyze-results.xml\\\"\\nThis will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\\r\\nThe output will be saved into the \\\"C:\\\\Temp\\\\d365fo.tools\\\\runbook-analyze-results.xml\\\" file.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eGet-D365Runbook | Backup-D365Runbook\\nThis will save a copy of all runbooks from the default location and save them to \\\"c:\\\\temp\\\\d365fo.tools\\\\runbookbackups\\\"\\n-------------------------- EXAMPLE 6 --------------------------\\nPS C:\\\\\\u003enotepad.exe (Get-D365Runbook -Latest).File\\nThis will find the latest runbook file and open it with notepad.\",\n        \"Syntax\":  \"Get-D365Runbook [[-Path] \\u003cString\\u003e] [[-Name] \\u003cString\\u003e] [-Latest] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365RunbookId\",\n        \"Description\":  \"Get the runbook id from inside a runbook file\",\n        \"Tags\":  [\n                     \"Runbook\",\n                     \"Analyze\",\n                     \"RunbookId\",\n                     \"Runbooks\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the runbook file that you want to analyse\\nAccepts value from pipeline, also by property\",\n                           \"File\",\n                           true,\n                           \"true (ByValue, ByPropertyName)\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get runbook id\",\n        \"Name\":  \"Get-D365RunbookId\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365RunbookId -Path \\\"C:\\\\DynamicsAX\\\\InstallationRecords\\\\Runbooks\\\\Runbook.xml\\\"\\nThis will inspect the Runbook.xml file and output the runbookid from inside the XML document.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365Runbook | Get-D365RunbookId\\nThis will find all runbook file(s) and have them analyzed by the Get-D365RunbookId cmdlet to output the runbookid(s).\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365Runbook -Latest | Get-D365RunbookId\\nThis will find the latest runbook file and have it analyzed by the Get-D365RunbookId cmdlet to output the runbookid.\",\n        \"Syntax\":  \"Get-D365RunbookId [-Path] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365RunbookLogFile\",\n        \"Description\":  \"Get the log files for a specific Runbook step\",\n        \"Tags\":  [\n                     \"Runbook\",\n                     \"Servicing\",\n                     \"Hotfix\",\n                     \"DeployablePackage\",\n                     \"Deployable Package\",\n                     \"InstallationRecordsDirectory\",\n                     \"Installation Records Directory\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to Software Deployable Package that was run in connection with the runbook\",\n                           \"File\",\n                           true,\n                           \"true (ByValue, ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"Step\",\n                           \"Step id for the step that you want to locate the log files for\",\n                           \"StepId\",\n                           true,\n                           \"true (ByValue, ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"Latest\",\n                           \"Instruct the cmdlet to only work with the latest log file\\nIs based on the last written attribute on the log file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OpenInEditor\",\n                           \"Instruct the cmdlet to open the log file in the default text editor\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get log file from a Runbook step\",\n        \"Name\":  \"Get-D365RunbookLogFile\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365RunbookLogFile -Path \\\"C:\\\\Temp\\\\PU35\\\" -Step 34\\nThis will locate all logfiles that has been outputted from the Step 34 from the PU35 installation.\\r\\nThe output will list the complete path to the log files.\\nAn output example:\\nFilename     : AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log\\r\\nLastModified : 8/7/2020 12:40:34 PM\\r\\nFile         : C:\\\\Temp\\\\PU35\\\\RunbookWorkingFolder\\\\Runbook\\\\MININT-F36S5EH\\\\DIXFService\\\\34\\\\Log\\\\AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log\\nFilename     : AutoUpdateDIXFService.ps1-2020-07-8--12-36-22.log\\r\\nLastModified : 8/7/2020 12:36:22 PM\\r\\nFile         : C:\\\\Temp\\\\PU35\\\\RunbookWorkingFolder\\\\Runbook\\\\MININT-F36S5EH\\\\DIXFService\\\\34\\\\Log\\\\AutoUpdateDIXFService.ps1-2020-07-8--12-36-22.log\\nFilename     : AutoUpdateDIXFService.ps1-2020-05-8--19-15-07.log\\r\\nLastModified : 8/5/2020 7:15:07 PM\\r\\nFile         : C:\\\\Temp\\\\PU35\\\\RunbookWorkingFolder\\\\Runbook\\\\MININT-F36S5EH\\\\DIXFService\\\\34\\\\Log\\\\AutoUpdateDIXFService.ps1-2020-05-8--19-15-07.log\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365RunbookLogFile -Path \\\"C:\\\\Temp\\\\PU35\\\" -Step 34 -Latest\\nThis will locate all logfiles that has been outputted from the Step 34 from the PU35 installation.\\r\\nThe output will be limited to the latest log, based on last write time.\\r\\nThe output will list the complete path to the log file.\\nAn output example:\\nFilename     : AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log\\r\\nLastModified : 8/7/2020 12:40:34 PM\\r\\nFile         : C:\\\\Temp\\\\PU35\\\\RunbookWorkingFolder\\\\Runbook\\\\MININT-F36S5EH\\\\DIXFService\\\\34\\\\Log\\\\AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365RunbookLogFile -Path \\\"C:\\\\Temp\\\\PU35\\\" -Step 34 -OpenInEditor\\nThis will locate all logfiles that has been outputted from the Step 34 from the PU35 installation.\\r\\nThe Get-D365RunbookLogFile will open all log files in the default text editor.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365RunbookLogFile -Path \\\"C:\\\\Temp\\\\PU35\\\" -Step 34 -Latest -OpenInEditor\\nThis will locate all logfiles that has been outputted from the Step 34 from the PU35 installation.\\r\\nThe output will be limited to the latest log, based on last write time.\\r\\nThe Get-D365RunbookLogFile will open the log file in the default text editor.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eGet-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnlyAsObjects | Get-D365RunbookLogFile -Path \\\"C:\\\\Temp\\\\PU35\\\" -OpenInEditor\\nThis will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\\r\\nThe output from Invoke-D365RunbookAnalyzer will only contain failed steps.\\r\\nThe Get-D365RunbookLogFile will open all log files for the failed step.\",\n        \"Syntax\":  \"Get-D365RunbookLogFile [-Path] \\u003cString\\u003e [-Step] \\u003cString\\u003e [-Latest] [-OpenInEditor] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365SDPCleanUp\",\n        \"Description\":  \"Gets the configured retention period before updates are deleted\",\n        \"Tags\":  [\n                     \"CleanUp\",\n                     \"Retention\",\n                     \"Servicing\",\n                     \"Cut Off\",\n                     \"DeployablePackage\",\n                     \"Deployable Package\"\n                 ],\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the cleanup retention period\",\n        \"Name\":  \"Get-D365SDPCleanUp\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365SDPCleanUp\\nThis will get the configured retention period from the registry\",\n        \"Syntax\":  \"Get-D365SDPCleanUp [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365SDPDetails\",\n        \"Description\":  \"Details details about the inner modules / packages that a Software Deployable Contains\",\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the Software Deployable Package that you want to work against\\nThe cmdlet supports a path to a zip-file or directory with the unpacked content\",\n                           \"File\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get details from the Software Deployable Package\",\n        \"Name\":  \"Get-D365SDPDetails\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365SDPDetails -Path \\u0027C:\\\\Temp\\\\RV-10.0.36.44.zip\\u0027\\nThis will display the basic details about the package.\\r\\nThe package is a zip file.\\nA result set example:\\nPlatform PlatformVersion Modules\\r\\n-------- --------------- -------\\r\\nUpdate55 7.0.6651.92     {@{Name=RapidValue; Version=7.0.6651.92}, @{Name=TCLCommon; Version=7.0.6651.92}, @{Name=TC...\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365SDPDetails -Path \\u0027C:\\\\Temp\\\\RV-10.0.36.44\\u0027\\nThis will display the basic details about the package.\\r\\nThe package is extracted to a local folder.\\nA result set example:\\nPlatform PlatformVersion Modules\\r\\n-------- --------------- -------\\r\\nUpdate55 7.0.6651.92     {@{Name=RapidValue; Version=7.0.6651.92}, @{Name=TCLCommon; Version=7.0.6651.92}, @{Name=TC...\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365SDPDetails -Path \\u0027C:\\\\Temp\\\\RV-10.0.36.44.zip\\u0027 | Select-Object -ExpandProperty Modules\\nThis will display the module details that are part of the package.\\r\\nThe package is a zip file.\\nA result set example:\\nName       Version\\r\\n----       -------\\r\\nRapidValue 7.0.6651.92\\r\\nTCLCommon  7.0.6651.92\\r\\nTCLLabel   7.0.6651.92\",\n        \"Syntax\":  \"Get-D365SDPDetails [-Path] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365Table\",\n        \"Description\":  \"Get a table either by TableName (wildcard search allowed) or by TableId\",\n        \"Tags\":  [\n                     \"Table\",\n                     \"Tables\",\n                     \"AOT\",\n                     \"TableId\",\n                     \"Development\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"Name of the table that you are looking for\\nAccepts wildcards for searching. E.g. -Name \\\"Cust*\\\"\\nDefault value is \\\"*\\\" which will search for all tables\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"Id\",\n                           \"The specific id for the table you are looking for\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"0\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@splaxi)\",\n        \"Synopsis\":  \"Get a table\",\n        \"Name\":  \"Get-D365Table\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365Table -Name CustTable\\nWill get the details for the CustTable\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365Table -Id 10347\\nWill get the details for the table with the id 10347.\",\n        \"Syntax\":  \"Get-D365Table [[-Name] \\u003cString[]\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\\nGet-D365Table [-Id] \\u003cInt32\\u003e [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365TableField\",\n        \"Description\":  \"Get a field either by FieldName (wildcard search allowed) or by FieldId\",\n        \"Tags\":  [\n                     \"Table\",\n                     \"Tables\",\n                     \"Fields\",\n                     \"TableField\",\n                     \"Table Field\",\n                     \"TableName\",\n                     \"TableId\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"TableId\",\n                           \"The id of the table that the field belongs to\",\n                           \"\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"0\"\n                       ],\n                       [\n                           \"Name\",\n                           \"Name of the field that you are looking for\\nAccepts wildcards for searching. E.g. -Name \\\"Account*\\\"\\nDefault value is \\\"*\\\" which will search for all fields\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"FieldId\",\n                           \"Id of the field that you are looking for\\nType is integer\",\n                           \"\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"0\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"TableName\",\n                           \"Name of the table that the field belongs to\\nSearch will only return the first hit (unordered) and work against that hit\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"IncludeTableDetails\",\n                           \"Switch options to enable the result set to include extended details\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"SearchAcrossTables\",\n                           \"Switch options to force the cmdlet to search across all tables when looking for the field\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@splaxi)\",\n        \"Synopsis\":  \"Get a field from table\",\n        \"Name\":  \"Get-D365TableField\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365TableField -TableId 10347\\nWill get all field details for the table with id 10347.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365TableField -TableName CustTable\\nWill get all field details for the CustTable table.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365TableField -TableId 10347 -FieldId 175\\nWill get the details for the field with id 175 that belongs to the table with id 10347.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365TableField -TableId 10347 -Name \\\"VATNUM\\\"\\nWill get the details for the \\\"VATNUM\\\" that belongs to the table with id 10347.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eGet-D365TableField -TableId 10347 -Name \\\"VAT*\\\"\\nWill get the details for all fields that fits the search \\\"VAT*\\\" that belongs to the table with id 10347.\\n-------------------------- EXAMPLE 6 --------------------------\\nPS C:\\\\\\u003eGet-D365TableField -Name AccountNum -SearchAcrossTables\\nWill search for the AccountNum field across all tables.\\n-------------------------- EXAMPLE 7 --------------------------\\nPS C:\\\\\\u003eGet-D365TableField -TableName CustTable -IncludeTableDetails\\nWill get all field details for the CustTable table.\\r\\nWill include table details in the output.\",\n        \"Syntax\":  \"Get-D365TableField [-TableId] \\u003cInt32\\u003e [[-Name] \\u003cString\\u003e] [[-FieldId] \\u003cInt32\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [-IncludeTableDetails] [\\u003cCommonParameters\\u003e]\\nGet-D365TableField [[-Name] \\u003cString\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [-SearchAcrossTables] [\\u003cCommonParameters\\u003e]\\nGet-D365TableField [[-Name] \\u003cString\\u003e] [[-FieldId] \\u003cInt32\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [-TableName] \\u003cString\\u003e [-IncludeTableDetails] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365TableSequence\",\n        \"Description\":  \"Get the sequence details for tables\",\n        \"Tags\":  [\n                     \"Table\",\n                     \"RecId\",\n                     \"Sequence\",\n                     \"Record Id\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"TableName\",\n                           \"Name of the table that you want to work against\\nAccepts wildcards for searching. E.g. -TableName \\\"Cust*\\\"\\nDefault value is \\\"*\\\" which will search for all tables\",\n                           \"Name\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"*\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the sequence object for table\",\n        \"Name\":  \"Get-D365TableSequence\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365TableSequence | Format-Table\\nThis will get all the sequence details for all tables inside the database.\\r\\nIt will format the output as a table for better overview.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365TableSequence -TableName \\\"Custtable\\\" | Format-Table\\nThis will get the sequence details for the CustTable in the database.\\r\\nIt will format the output as a table for better overview.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365TableSequence -TableName \\\"Cust*\\\" | Format-Table\\nThis will get the sequence details for all tables that matches the search \\\"Cust*\\\" in the database.\\r\\nIt will format the output as a table for better overview.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365Table -Name CustTable | Get-D365TableSequence | Format-Table\\nThis will get the table details from the Get-D365Table cmdlet and pipe that into Get-D365TableSequence.\\r\\nThis will get the sequence details for the CustTable in the database.\\r\\nIt will format the output as a table for better overview.\",\n        \"Syntax\":  \"Get-D365TableSequence [[-TableName] \\u003cString\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365TablesInChangedTracking\",\n        \"Description\":  \"Get table(s) that is taking part of the SQL Server Change Tracking mechanism\",\n        \"Tags\":  [\n                     \"Table\",\n                     \"Change Tracking\",\n                     \"Tablename\",\n                     \"DMF\",\n                     \"DIXF\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"Name of the table that you are looking for\\nAccepts wildcards for searching. E.g. -Name \\\"Cust*\\\"\\nDefault value is \\\"*\\\" which will search for all tables\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@splaxi)\",\n        \"Synopsis\":  \"Get table that is taking part of Change Tracking\",\n        \"Name\":  \"Get-D365TablesInChangedTracking\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365TablesInChangedTracking\\nThis will list all tables that are taking part in the SQL Server Change Tracking.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365TablesInChangedTracking -Name CustTable\\nThis will search for a table in the list of tables that are taking part in the SQL Server Change Tracking.\\r\\nIt will use the CustTable as the search pattern while searching for the table.\",\n        \"Syntax\":  \"Get-D365TablesInChangedTracking [[-Name] \\u003cString\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365TfsUri\",\n        \"Description\":  \"Gets the URI from the configuration of the local tfs connection in visual studio\",\n        \"Tags\":  [\n                     \"TFS\",\n                     \"VSTS\",\n                     \"URL\",\n                     \"URI\",\n                     \"Servicing\",\n                     \"Development\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the tf.exe file that the cmdlet will invoke\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:TfDir\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the TFS / VSTS registered URL / URI\",\n        \"Name\":  \"Get-D365TfsUri\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365TfsUri\\nThis will invoke the default tf.exe client located in the Visual Studio 2015 directory\\r\\nand fetch the configured URI.\",\n        \"Syntax\":  \"Get-D365TfsUri [[-Path] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365TfsWorkspace\",\n        \"Description\":  \"Gets the workspace path from the configuration of the local tfs in visual studio\",\n        \"Tags\":  [\n                     \"TFS\",\n                     \"VSTS\",\n                     \"URL\",\n                     \"URI\",\n                     \"Servicing\",\n                     \"Development\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the directory where the Team Foundation Client executable is located\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:TfDir\"\n                       ],\n                       [\n                           \"TfsUri\",\n                           \"Uri to the TFS / VSTS that the workspace is connected to\",\n                           \"\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"$Script:TfsUri\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the TFS / VSTS registered workspace path\",\n        \"Name\":  \"Get-D365TfsWorkspace\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365TfsWorkspace -TfsUri https://PROJECT.visualstudio.com\\nThis will invoke the default tf.exe client located in the Visual Studio 2015 directory\\r\\nand fetch the configured URI.\",\n        \"Syntax\":  \"Get-D365TfsWorkspace [[-Path] \\u003cString\\u003e] [[-TfsUri] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365Url\",\n        \"Description\":  \"Get the complete URL for accessing the Dynamics 365 Finance \\u0026 Operations instance running on this machine\",\n        \"Tags\":  [\n                     \"URL\",\n                     \"URI\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Force\",\n                           \"Switch to instruct the cmdlet to retrieve the name from the system files\\r\\ninstead of the name stored in memory after loading this module.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Rasmus Andersen (@ITRasmus)\",\n        \"Synopsis\":  \"Get the url for accessing the instance\",\n        \"Name\":  \"Get-D365Url\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365Url\\nThis will get the correct URL to access the environment\",\n        \"Syntax\":  \"Get-D365Url [-Force] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365User\",\n        \"Description\":  \"Get all relevant user details from the Dynamics 365 for Finance \\u0026 Operations\",\n        \"Tags\":  [\n                     \"User\",\n                     \"Users\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"Email\",\n                           \"The search string to select which user(s) should be updated\\nThe parameter supports wildcards. E.g. -Email \\\"*@contoso.com*\\\"\\nDefault value is \\\"*\\\" to get all users\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"ExcludeSystemUsers\",\n                           \"Instructs the cmdlet to filter out all known system users\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get users from the environment\",\n        \"Name\":  \"Get-D365User\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365User\\nThis will get all users from the environment.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365User -ExcludeSystemUsers\\nThis will get all users from the environment, but filter out all known system user accounts.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365User -Email \\\"*contoso.com\\\"\\nThis will search for all users with an e-mail address containing \\u0027contoso.com\\u0027 from the environment.\",\n        \"Syntax\":  \"Get-D365User [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [[-Email] \\u003cString\\u003e] [-ExcludeSystemUsers] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365UserAuthenticationDetail\",\n        \"Description\":  \"The cmdlet will take the e-mail parameter and use it to lookup all the needed details for configuring authentication against Dynamics 365 Finance \\u0026 Operations\",\n        \"Tags\":  [\n                     \"User\",\n                     \"Users\",\n                     \"Security\",\n                     \"Configuration\",\n                     \"Authentication\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Email\",\n                           \"The e-mail address / login name of the user that the cmdlet must gather details about\",\n                           \"\",\n                           true,\n                           \"true (ByValue)\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Synopsis\":  \"Cmdlet used to get authentication details about a user\",\n        \"Name\":  \"Get-D365UserAuthenticationDetail\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365UserAuthenticationDetail -Email \\\"Claire@contoso.com\\\"\\nThis will get all the authentication details for the user account with the email address \\\"Claire@contoso.com\\\"\",\n        \"Syntax\":  \"Get-D365UserAuthenticationDetail [-Email] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365VisualStudioCompilerResult\",\n        \"Description\":  \"Get the Visual Studio compiler outputs presented in a structured manner on the screen\",\n        \"Tags\":  [\n                     \"Compiler\",\n                     \"Build\",\n                     \"Errors\",\n                     \"Warnings\",\n                     \"Tasks\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Module\",\n                           \"Name of the module that you want to work against\\nDefault value is \\\"*\\\" which will search for all modules\",\n                           \"ModuleName\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"ErrorsOnly\",\n                           \"Instructs the cmdlet to only output compile results where there was errors detected\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputTotals\",\n                           \"Instructs the cmdlet to output the total errors and warnings after the analysis\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputAsObjects\",\n                           \"Instructs the cmdlet to output the objects instead of formatting them\\nIf you don\\u0027t assign the output, it will be formatted the same way as the original output, but without the coloring of the column values\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nDefault path is the same as the AOS service \\\"PackagesLocalDirectory\\\" directory\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get the compiler outputs presented\",\n        \"Name\":  \"Get-D365VisualStudioCompilerResult\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365VisualStudioCompilerResult\\nThis will return the compiler output for all modules.\\nA result set example:\\nFile                                                                                     Warnings Errors\\r\\n----                                                                                     -------- ------\\r\\nK:\\\\AosService\\\\PackagesLocalDirectory\\\\ApplicationCommon\\\\BuildModelResult.log                    55      0\\r\\nK:\\\\AosService\\\\PackagesLocalDirectory\\\\ApplicationFoundation\\\\BuildModelResult.log               692      0\\r\\nK:\\\\AosService\\\\PackagesLocalDirectory\\\\ApplicationPlatform\\\\BuildModelResult.log                 155      0\\r\\nK:\\\\AosService\\\\PackagesLocalDirectory\\\\ApplicationSuite\\\\BuildModelResult.log                  10916      0\\r\\nK:\\\\AosService\\\\PackagesLocalDirectory\\\\CustomModule\\\\BuildModelResult.log                          1      2\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365VisualStudioCompilerResult -ErrorsOnly\\nThis will return the compiler output for all modules where there was errors in.\\nA result set example:\\nFile                                                                                     Warnings Errors\\r\\n----                                                                                     -------- ------\\r\\nK:\\\\AosService\\\\PackagesLocalDirectory\\\\CustomModule\\\\BuildModelResult.log                          1      2\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365VisualStudioCompilerResult -ErrorsOnly -OutputAsObjects\\nThis will return the compiler output for all modules where there was errors in.\\r\\nThe output will be PSObjects, which can be assigned to a variable and used for futher analysis.\\nA result set example:\\nFile                                                                                     Warnings Errors\\r\\n----                                                                                     -------- ------\\r\\nK:\\\\AosService\\\\PackagesLocalDirectory\\\\CustomModule\\\\BuildModelResult.log                          1      2\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365VisualStudioCompilerResult -OutputTotals\\nThis will return the compiler output for all modules and write a total overview to the console.\\nA result set example:\\nFile                                                                                     Warnings Errors\\r\\n----                                                                                     -------- ------\\r\\nK:\\\\AosService\\\\PackagesLocalDirectory\\\\ApplicationCommon\\\\BuildModelResult.log                    55      0\\r\\nK:\\\\AosService\\\\PackagesLocalDirectory\\\\ApplicationFoundation\\\\BuildModelResult.log               692      0\\r\\nK:\\\\AosService\\\\PackagesLocalDirectory\\\\ApplicationPlatform\\\\BuildModelResult.log                 155      0\\r\\nK:\\\\AosService\\\\PackagesLocalDirectory\\\\ApplicationSuite\\\\BuildModelResult.log                  10916      0\\r\\nK:\\\\AosService\\\\PackagesLocalDirectory\\\\CustomModule\\\\BuildModelResult.log                          1      2\\nTotal Errors: 2\\r\\nTotal Warnings: 11819\",\n        \"Syntax\":  \"Get-D365VisualStudioCompilerResult [[-Module] \\u003cString\\u003e] [-ErrorsOnly] [-OutputTotals] [-OutputAsObjects] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365WebServerType\",\n        \"Description\":  \"Get the web server which will be used to run D365FO: Either IIS or IIS Express.\\nNewly deployed development machines will have this set to IIS Express by default.\\n\\nIt will look for the file located in the default Package Directory.\",\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Sander Holvoet (@smholvoet)\",\n        \"Synopsis\":  \"Get the default web server to be used\",\n        \"Name\":  \"Get-D365WebServerType\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365WebServerType\\nThis will display the current web server type registered in the \\\"DynamicsDevConfig.xml\\\" file.\\r\\nLocated in \\\"K:\\\\AosService\\\\PackagesLocalDirectory\\\\bin\\\".\",\n        \"Syntax\":  \"Get-D365WebServerType [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Get-D365WindowsActivationStatus\",\n        \"Description\":  \"Get all the important license and activation information from the machine\",\n        \"Tags\":  [\n                     \"Windows\",\n                     \"License\",\n                     \"Activation\",\n                     \"Arm\",\n                     \"Rearm\"\n                 ],\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Get activation status\",\n        \"Name\":  \"Get-D365WindowsActivationStatus\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eGet-D365WindowsActivationStatus\\nThis will get the remaining grace and rearm activation information for the machine\",\n        \"Syntax\":  \"Get-D365WindowsActivationStatus [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Import-D365AadApplication\",\n        \"Description\":  \"Provides a method for importing a AAD application into D365FO.\",\n        \"Tags\":  [\n                     \"User\",\n                     \"Users\",\n                     \"Security\",\n                     \"Configuration\",\n                     \"Permission\",\n                     \"AAD\",\n                     \"Azure Active Directory\",\n                     \"Group\",\n                     \"Groups\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"The name that the imported application should have inside the D365FO environment\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"UserId\",\n                           \"The id of the user linked to the application inside the D365FO environment\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ClientId\",\n                           \"The Client ID that the imported application should use inside the D365FO environment\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Gert Van Der Heyden (@gertvdheyden)\",\n        \"Synopsis\":  \"Used to import Aad applications into D365FO\",\n        \"Name\":  \"Import-D365AadApplication\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eImport-D365AadApplication -Name \\\"Application1\\\" -UserId \\\"admin\\\" -ClientId \\\"aef2e67c-64a3-4c72-9294-d288c5bf503d\\\"\\nImports Application1 as an application linked to user admin into the D365FO environment.\",\n        \"Syntax\":  \"Import-D365AadApplication [-Name] \\u003cString\\u003e [-UserId] \\u003cString\\u003e [-ClientId] \\u003cString\\u003e [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Import-D365AadUser\",\n        \"Description\":  \"Provides a method for importing a AAD UserGroup or a comma separated list of AadUsers into D365FO.\",\n        \"Tags\":  [\n                     \"User\",\n                     \"Users\",\n                     \"Security\",\n                     \"Configuration\",\n                     \"Permission\",\n                     \"AAD\",\n                     \"Azure Active Directory\",\n                     \"Group\",\n                     \"Groups\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"AadGroupName\",\n                           \"Azure Active directory user group containing users to be imported\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Users\",\n                           \"Array of users that you want to import into the D365FO environment\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"StartupCompany\",\n                           \"Startup company of users imported.\\nDefault is DAT\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"DAT\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"IdPrefix\",\n                           \"A text that will be prefixed into the ID field. E.g. -IdPrefix \\\"EXT-\\\" will import users and set ID starting with \\\"EXT-...\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"NameSuffix\",\n                           \"A text that will be suffixed into the NAME field. E.g. -NameSuffix \\\"(Contoso)\\\" will import users and append \\\"(Contoso)\\\"\\\" to the NAME\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"IdValue\",\n                           \"Specify which field to use as ID value when importing the users.\\r\\nAvailable options \\u0027Login\\u0027 / \\u0027FirstName\\u0027 / \\u0027UserPrincipalName\\u0027\\nDefault is \\u0027Login\\u0027\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"Login\"\n                       ],\n                       [\n                           \"NameValue\",\n                           \"Specify which field to use as NAME value when importing the users.\\r\\nAvailable options \\u0027FirstName\\u0027 / \\u0027DisplayName\\u0027\\nDefault is \\u0027DisplayName\\u0027\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"DisplayName\"\n                       ],\n                       [\n                           \"AzureAdCredential\",\n                           \"Use a PSCredential object for connecting with AzureAd\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"SkipAzureAd\",\n                           \"Switch to instruct the cmdlet to skip validating against the Azure Active Directory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"ForceExactAadGroupName\",\n                           \"Force to find the exact name of the Azure Active Directory Group\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"AadGroupId\",\n                           \"Azure Active directory user group ID containing users to be imported\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"EmailValue\",\n                           \"Specify which field to use as EMAIL value when importing the users.\\r\\nAvailable options \\u0027Mail\\u0027 / \\u0027UserPrincipalName\\u0027\\nDefault is \\u0027Mail\\u0027\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"Mail\"\n                       ],\n                       [\n                           \"TenantId\",\n                           \"The TenantId to use when connecting to Azure Active Directory\\nUses the tenant id of the current environment if not specified.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:TenantId\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Rasmus Andersen (@ITRasmus)\",\n        \"Synopsis\":  \"Used to import Aad users into D365FO\",\n        \"Name\":  \"Import-D365AadUser\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eImport-D365AadUser -Users \\\"Claire@contoso.com\\\",\\\"Allen@contoso.com\\\"\\nImports Claire and Allen as users\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003e$myPassword = ConvertTo-SecureString \\\"MyPasswordIsSecret\\\" -AsPlainText -Force\\nPS C:\\\\\\u003e $myCredentials = New-Object System.Management.Automation.PSCredential (\\\"MyEmailIsAlso\\\", $myPassword)\\nPS C:\\\\\\u003e Import-D365AadUser -Users \\\"Claire@contoso.com\\\",\\\"Allen@contoso.com\\\" -AzureAdCredential $myCredentials\\nThis will import Claire and Allen as users.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eImport-D365AadUser -AadGroupName \\\"CustomerTeam1\\\"\\nif more than one group match the AadGroupName, you can use the ExactAadGroupName parameter\\r\\nImport-D365AadUser -AadGroupName \\\"CustomerTeam1\\\" -ForceExactAadGroupName\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eImport-D365AadUser -AadGroupName \\\"CustomerTeam1\\\" -ForceExactAadGroupName\\nThis is used to force the cmdlet to find the exact named group in Azure Active Directory.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eImport-D365AadUser -AadGroupId \\\"99999999-aaaa-bbbb-cccc-9999999999\\\"\\nImports all the users that is present in the AAD Group called CustomerTeam1\\n-------------------------- EXAMPLE 6 --------------------------\\nPS C:\\\\\\u003eImport-D365AadUser -Users \\\"Claire@contoso.com\\\",\\\"Allen@contoso.com\\\" -SkipAzureAd\\nImports Claire and Allen as users.\\r\\nWill NOT make you connect to the Azure Active Directory(AAD).\\r\\nThe needed details will be based on the e-mail address only, and the rest will be blanked.\\n-------------------------- EXAMPLE 7 --------------------------\\nPS C:\\\\\\u003eImport-D365AadUser -Users \\\"Claire@contoso.com\\\",\\\"Allen@contoso.com\\\" -TenantId \\\"99999999-aaaa-bbbb-cccc-9999999999\\\"\\nImports Claire and Allen as users. Uses tenant id \\\"99999999-aaaa-bbbb-cccc-9999999999\\\"\\r\\nwhen connecting to Azure Active Directory(AAD).\",\n        \"Syntax\":  \"Import-D365AadUser [-Users] \\u003cString[]\\u003e [[-StartupCompany] \\u003cString\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [[-IdPrefix] \\u003cString\\u003e] [[-NameSuffix] \\u003cString\\u003e] [[-IdValue] \\u003cString\\u003e] [[-NameValue] \\u003cString\\u003e] [[-AzureAdCredential] \\u003cPSCredential\\u003e] [[-SkipAzureAd]] [[-EmailValue] \\u003cString\\u003e] [[-TenantId] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\\nImport-D365AadUser [-AadGroupName] \\u003cString\\u003e [[-StartupCompany] \\u003cString\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [[-IdPrefix] \\u003cString\\u003e] [[-NameSuffix] \\u003cString\\u003e] [[-IdValue] \\u003cString\\u003e] [[-NameValue] \\u003cString\\u003e] [[-AzureAdCredential] \\u003cPSCredential\\u003e] [[-ForceExactAadGroupName]] [[-EmailValue] \\u003cString\\u003e] [[-TenantId] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\\nImport-D365AadUser [[-StartupCompany] \\u003cString\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [[-IdPrefix] \\u003cString\\u003e] [[-NameSuffix] \\u003cString\\u003e] [[-IdValue] \\u003cString\\u003e] [[-NameValue] \\u003cString\\u003e] [[-AzureAdCredential] \\u003cPSCredential\\u003e] [-AadGroupId] \\u003cString\\u003e [[-EmailValue] \\u003cString\\u003e] [[-TenantId] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Import-D365Bacpac\",\n        \"Description\":  \"Import a bacpac file to either a Tier1 or Tier2 environment\",\n        \"Tags\":  [\n                     \"Database\",\n                     \"Bacpac\",\n                     \"Tier1\",\n                     \"Tier2\",\n                     \"Golden Config\",\n                     \"Config\",\n                     \"Configuration\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"ImportModeTier1\",\n                           \"Switch to instruct the cmdlet that it will import into a Tier1 environment\\nThe cmdlet will expect to work against a SQL Server instance\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"ImportModeTier2\",\n                           \"Switch to instruct the cmdlet that it will import into a Tier2 environment\\nThe cmdlet will expect to work against an Azure DB instance\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"BacpacFile\",\n                           \"Path to the bacpac file you want to import into the database server\",\n                           \"File\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"NewDatabaseName\",\n                           \"Name of the new database that will be created while importing the bacpac file\\nThis will create a new database on the database server and import the content of the bacpac into\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"AxDeployExtUserPwd\",\n                           \"Password that is obtained from LCS\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"AxDbAdminPwd\",\n                           \"Password that is obtained from LCS\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"AxRuntimeUserPwd\",\n                           \"Password that is obtained from LCS\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"AxMrRuntimeUserPwd\",\n                           \"Password that is obtained from LCS\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"AxRetailRuntimeUserPwd\",\n                           \"Password that is obtained from LCS\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"AxRetailDataSyncUserPwd\",\n                           \"Password that is obtained from LCS\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"AxDbReadonlyUserPwd\",\n                           \"Password that is obtained from LCS\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"CustomSqlFile\",\n                           \"Path to the sql script file that you want the cmdlet to execute against your data after it has been imported\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ModelFile\",\n                           \"Path to the model file that you want the SqlPackage.exe to use instead the one being part of the bacpac file\\nThis is used to override SQL Server options, like collation and etc\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"DiagnosticFile\",\n                           \"Path to where you want the import to output a diagnostics file to assist you in troubleshooting the import\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ImportOnly\",\n                           \"Switch to instruct the cmdlet to only import the bacpac into the new database\\nThe cmdlet will create a new database and import the content of the bacpac file into this\\nNothing else will be executed\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"MaxParallelism\",\n                           \"Sets SqlPackage.exe\\u0027s degree of parallelism for concurrent operations running against a database\\nThe default value is 8\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"8\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"The path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\ImportBacpac\\\")\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Properties\",\n                           \"String array of properties to be used by SQLPackage.exe\\r\\nSee https://learn.microsoft.com/en-us/sql/tools/sqlpackage/sqlpackage-import#properties-specific-to-the-import-action for more information.\\r\\nNote that some properties are already set by the cmdlet, and cannot be overridden.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Rasmus Andersen (@ITRasmus)\",\n        \"Synopsis\":  \"Import a bacpac file\",\n        \"Name\":  \"Import-D365Bacpac\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365InstallSqlPackage\\nYou should always install the latest version of the SqlPackage.exe, which is used by New-D365Bacpac.\\nThis will fetch the latest .Net Core Version of SqlPackage.exe and install it at \\\"C:\\\\temp\\\\d365fo.tools\\\\SqlPackage\\\".\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eImport-D365Bacpac -ImportModeTier1 -BacpacFile \\\"C:\\\\temp\\\\uat.bacpac\\\" -NewDatabaseName \\\"ImportedDatabase\\\"\\nPS C:\\\\\\u003e Switch-D365ActiveDatabase -NewDatabaseName \\\"ImportedDatabase\\\"\\nThis will instruct the cmdlet that the import will be working against a SQL Server instance.\\r\\nIt will import the \\\"C:\\\\temp\\\\uat.bacpac\\\" file into a new database named \\\"ImportedDatabase\\\".\\r\\nThe next thing to do is to switch the active database out with the new one you just imported.\\r\\n\\\"ImportedDatabase\\\" will be switched in as the active database, while the old one will be named \\\"AXDB_original\\\".\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eImport-D365Bacpac -ImportModeTier2 -SqlUser \\\"sqladmin\\\" -SqlPwd \\\"XyzXyz\\\" -BacpacFile \\\"C:\\\\temp\\\\uat.bacpac\\\" -AxDeployExtUserPwd \\\"XxXx\\\" -AxDbAdminPwd \\\"XxXx\\\" -AxRuntimeUserPwd \\\"XxXx\\\" \\r\\n-AxMrRuntimeUserPwd \\\"XxXx\\\" -AxRetailRuntimeUserPwd \\\"XxXx\\\" -AxRetailDataSyncUserPwd \\\"XxXx\\\" -AxDbReadonlyUserPwd \\\"XxXx\\\" -NewDatabaseName \\\"ImportedDatabase\\\"\\nPS C:\\\\\\u003e Switch-D365ActiveDatabase -NewDatabaseName \\\"ImportedDatabase\\\" -SqlUser \\\"sqladmin\\\" -SqlPwd \\\"XyzXyz\\\"\\nThis will instruct the cmdlet that the import will be working against an Azure DB instance.\\r\\nIt requires all relevant passwords from LCS for all the builtin user accounts used in a Tier 2 environment.\\r\\nIt will import the \\\"C:\\\\temp\\\\uat.bacpac\\\" file into a new database named \\\"ImportedDatabase\\\".\\r\\nThe next thing to do is to switch the active database out with the new one you just imported.\\r\\n\\\"ImportedDatabase\\\" will be switched in as the active database, while the old one will be named \\\"AXDB_original\\\".\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eImport-D365Bacpac -ImportModeTier1 -BacpacFile \\\"C:\\\\temp\\\\uat.bacpac\\\" -NewDatabaseName \\\"ImportedDatabase\\\" -DiagnosticFile \\\"C:\\\\temp\\\\ImportLog.txt\\\"\\nThis will instruct the cmdlet that the import will be working against a SQL Server instance.\\r\\nIt will import the \\\"C:\\\\temp\\\\uat.bacpac\\\" file into a new database named \\\"ImportedDatabase\\\".\\r\\nIt will output a diagnostic file to \\\"C:\\\\temp\\\\ImportLog.txt\\\".\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eImport-D365Bacpac -ImportModeTier1 -BacpacFile \\\"C:\\\\temp\\\\uat.bacpac\\\" -NewDatabaseName \\\"ImportedDatabase\\\" -DiagnosticFile \\\"C:\\\\temp\\\\ImportLog.txt\\\" -MaxParallelism 32\\nThis will instruct the cmdlet that the import will be working against a SQL Server instance.\\r\\nIt will import the \\\"C:\\\\temp\\\\uat.bacpac\\\" file into a new database named \\\"ImportedDatabase\\\".\\r\\nIt will output a diagnostic file to \\\"C:\\\\temp\\\\ImportLog.txt\\\".\\nIt will use 32 connections against the database server while importing the bacpac file.\\n-------------------------- EXAMPLE 6 --------------------------\\nPS C:\\\\\\u003eImport-D365Bacpac -ImportModeTier1 -BacpacFile \\\"C:\\\\temp\\\\uat.bacpac\\\" -NewDatabaseName \\\"ImportedDatabase\\\" -ImportOnly\\nThis will instruct the cmdlet that the import will be working against a SQL Server instance.\\r\\nIt will import the \\\"C:\\\\temp\\\\uat.bacpac\\\" file into a new database named \\\"ImportedDatabase\\\".\\r\\nNo cleanup or prepping jobs will be executed, because this is for importing only.\\nThis would be something that you can use when extract a bacpac file from a Tier1 and want to import it into a Tier1.\\r\\nYou would still need to execute the Switch-D365ActiveDatabase cmdlet, to get the newly imported database to be the AXDB database.\\n-------------------------- EXAMPLE 7 --------------------------\\nPS C:\\\\\\u003e[System.Collections.ArrayList] $PropertiesList = New-Object -TypeName \\\"System.Collections.ArrayList\\\"\\nPS C:\\\\\\u003e $PropertiesList.Add(\\\"DisableIndexesForDataPhase=false\\\")\\r\\nPS C:\\\\\\u003e Import-D365Bacpac -ImportModeTier1 -BacpacFile \\\"C:\\\\temp\\\\uat.bacpac\\\" -NewDatabaseName \\\"ImportedDatabase\\\" -Properties $PropertiesList.ToArray()\\nThis will instruct the cmdlet that the import will be working against a SQL Server instance.\\r\\nIt will import the \\\"C:\\\\temp\\\\uat.bacpac\\\" file into a new database named \\\"ImportedDatabase\\\".\\r\\nIt will use the DisableIndexesForDataPhase SQLPackage property to disable the index rebuild during the data phase of the import.\",\n        \"Syntax\":  \"Import-D365Bacpac [-ImportModeTier1] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [-BacpacFile] \\u003cString\\u003e [-NewDatabaseName] \\u003cString\\u003e [-CustomSqlFile \\u003cString\\u003e] [-ModelFile \\u003cString\\u003e] [-DiagnosticFile \\u003cString\\u003e] [-ImportOnly] [-MaxParallelism \\u003cInt32\\u003e] [-LogPath \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [-Properties \\u003cString[]\\u003e] [\\u003cCommonParameters\\u003e]\\nImport-D365Bacpac [-ImportModeTier2] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [-SqlUser] \\u003cString\\u003e [-SqlPwd] \\u003cString\\u003e [-BacpacFile] \\u003cString\\u003e [-NewDatabaseName] \\u003cString\\u003e [[-AxDeployExtUserPwd] \\u003cString\\u003e] [[-AxDbAdminPwd] \\u003cString\\u003e] [[-AxRuntimeUserPwd] \\u003cString\\u003e] [[-AxMrRuntimeUserPwd] \\u003cString\\u003e] [[-AxRetailRuntimeUserPwd] \\u003cString\\u003e] [[-AxRetailDataSyncUserPwd] \\u003cString\\u003e] [[-AxDbReadonlyUserPwd] \\u003cString\\u003e] [-CustomSqlFile \\u003cString\\u003e] [-ModelFile \\u003cString\\u003e] [-DiagnosticFile \\u003cString\\u003e] -ImportOnly [-MaxParallelism \\u003cInt32\\u003e] [-LogPath \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] \\r\\n[-EnableException] [-Properties \\u003cString[]\\u003e] [\\u003cCommonParameters\\u003e]\\nImport-D365Bacpac [-ImportModeTier2] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [-SqlUser] \\u003cString\\u003e [-SqlPwd] \\u003cString\\u003e [-BacpacFile] \\u003cString\\u003e [-NewDatabaseName] \\u003cString\\u003e [-AxDeployExtUserPwd] \\u003cString\\u003e [-AxDbAdminPwd] \\u003cString\\u003e [-AxRuntimeUserPwd] \\u003cString\\u003e [-AxMrRuntimeUserPwd] \\u003cString\\u003e [-AxRetailRuntimeUserPwd] \\u003cString\\u003e [-AxRetailDataSyncUserPwd] \\u003cString\\u003e [-AxDbReadonlyUserPwd] \\u003cString\\u003e [-CustomSqlFile \\u003cString\\u003e] [-ModelFile \\u003cString\\u003e] [-DiagnosticFile \\u003cString\\u003e] [-MaxParallelism \\u003cInt32\\u003e] [-LogPath \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [-Properties \\r\\n\\u003cString[]\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Import-D365Dacpac\",\n        \"Description\":  \"Import a dacpac file into a database, using the publish feature of SqlPackage.exe\\n\\nIf the database doesn\\u0027t exists, it will be created\\n\\nIf the database exists, the publish process from the dacpac file will make sure to align the different tables inside the database\",\n        \"Tags\":  [\n                     \"Database\",\n                     \"Dacpac\",\n                     \"Tier1\",\n                     \"Tier2\",\n                     \"Golden Config\",\n                     \"Config\",\n                     \"Configuration\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the dacpac file that you want to import\",\n                           \"File,Dacpac\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ModelFile\",\n                           \"Path to the model file that you want the SqlPackage.exe to use instead the one being part of the dacpac file\\nThis is used to override SQL Server options, like collation and etc\\nThis is also used to support single table import / restore from a dacpac file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"PublishFile\",\n                           \"Path to the publish / profile file that contains extended parameters for the SqlPackage.exe assembly\",\n                           \"ProfileFile\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"DiagnosticFile\",\n                           \"Path to where you want the import to output a diagnostics file to assist you in troubleshooting the import\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"MaxParallelism\",\n                           \"Sets SqlPackage.exe\\u0027s degree of parallelism for concurrent operations running against a database\\nThe default value is 8\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"8\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"The path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\ImportDacpac\\\")\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Import dacpac file to a database\",\n        \"Name\":  \"Import-D365Dacpac\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eImport-D365Dacpac -Path \\\"c:\\\\Temp\\\\AxDB.dacpac\\\" -ModelFile \\\"c:\\\\Temp\\\\dbo.salestable.model.xml\\\"\\nThis will import the dacpac file and use the modified model file while doing so.\\r\\nIt will use the \\\"c:\\\\Temp\\\\AxDB.dacpac\\\" as the Path parameter.\\r\\nIt will use the \\\"c:\\\\Temp\\\\dbo.salestable.model.xml\\\" as the ModelFile parameter.\\nThis is used to enable single table restore / publish.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eImport-D365Dacpac -Path \\\"c:\\\\Temp\\\\AxDB.dacpac\\\" -ModelFile \\\"c:\\\\Temp\\\\dbo.salestable.model.xml\\\" -DiagnosticFile \\\"C:\\\\temp\\\\ImportLog.txt\\\" -MaxParallelism 32\\nThis will import the dacpac file and use the modified model file while doing so.\\r\\nIt will use the \\\"c:\\\\Temp\\\\AxDB.dacpac\\\" as the Path parameter.\\r\\nIt will use the \\\"c:\\\\Temp\\\\dbo.salestable.model.xml\\\" as the ModelFile parameter.\\r\\nIt will use the \\\"C:\\\\temp\\\\ImportLog.txt\\\" as the DiagnosticFile parameter, where the diagnostic file will be stored.\\nIt will use 32 connections against the database server while importing the bacpac file.\\nThis is used to enable single table restore / publish.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eImport-D365Dacpac -Path \\\"c:\\\\Temp\\\\AxDB.dacpac\\\" -PublishFile \\\"c:\\\\Temp\\\\publish.xml\\\"\\nThis will import the dacpac file and use the Publish file which contains advanced configuration instructions for SqlPackage.exe.\\r\\nIt will use the \\\"c:\\\\Temp\\\\AxDB.dacpac\\\" as the Path parameter.\\r\\nIt will use the \\\"c:\\\\Temp\\\\publish.xml\\\" as the PublishFile parameter, which contains advanced configuration instructions for SqlPackage.exe.\\nThis is used to enable full restore / publish, but to avoid some of the common pitfalls.\",\n        \"Syntax\":  \"Import-D365Dacpac [-Path] \\u003cString\\u003e [[-ModelFile] \\u003cString\\u003e] [[-PublishFile] \\u003cString\\u003e] [[-DiagnosticFile] \\u003cString\\u003e] [[-MaxParallelism] \\u003cInt32\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [[-LogPath] \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Import-D365ExternalUser\",\n        \"Description\":  \"Imports an user from an AAD that is NOT the same as the AAD tenant that the D365FO environment is running under\",\n        \"Tags\":  [\n                     \"User\",\n                     \"Users\",\n                     \"Security\",\n                     \"Configuration\",\n                     \"Permission\",\n                     \"AAD\",\n                     \"Azure Active Directory\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Id\",\n                           \"The internal Id that the user must be imported with\\nThe Id has to unique across the entire user base\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Name\",\n                           \"The display name of the user inside the D365FO environment\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Email\",\n                           \"The email address of the user that you want to import\\nThis is also the sign-in user name / e-mail address to gain access to the system\\nIf the external AAD tenant has multiple custom domain names, you have to use the domain that they have configured as default\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Enabled\",\n                           \"Should the imported user be enabled or not?\\nDefault value is 1, which equals true / yes\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"1\"\n                       ],\n                       [\n                           \"Company\",\n                           \"Default company that should be configured for the user, for when they sign-in to the D365 environment\\nDefault value is \\\"DAT\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"DAT\"\n                       ],\n                       [\n                           \"Language\",\n                           \"Language that should be configured for the user, for when they sign-in to the D365 environment\\nDefault value is \\\"en-US\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"en-us\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Anderson Joyle (@AndersonJoyle)\",\n        \"Synopsis\":  \"Import an user from an external Azure Active Directory (AAD)\",\n        \"Name\":  \"Import-D365ExternalUser\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eImport-D365ExternalUser -Id \\\"John\\\" -Name \\\"John Doe\\\" -Email \\\"John@contoso.com\\\"\\nThis will import an user from an external Azure Active Directory.\\r\\nThe new user will get the system wide Id \\\"John\\\".\\r\\nThe name of the new user will be \\\"John Doe\\\".\\r\\nThe e-mail address / sign-in e-mail address will be registered as \\\"John@contoso.com\\\".\",\n        \"Syntax\":  \"Import-D365ExternalUser [-Id] \\u003cString\\u003e [-Name] \\u003cString\\u003e [-Email] \\u003cString\\u003e [[-Enabled] \\u003cInt32\\u003e] [[-Company] \\u003cString\\u003e] [[-Language] \\u003cString\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Import-D365Model\",\n        \"Description\":  \"Import a model into a Dynamics 365 for Finance \\u0026 Operations environment\",\n        \"Tags\":  [\n                     \"ModelUtil\",\n                     \"Axmodel\",\n                     \"Model\",\n                     \"Import\",\n                     \"Replace\",\n                     \"Source Control\",\n                     \"Vsts\",\n                     \"Azure DevOps\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the axmodel file that you want to import\",\n                           \"File\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the AOS service PackagesLocalDirectory\\\\bin\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:PackageDirectory\\\\bin\\\"\"\n                       ],\n                       [\n                           \"MetaDataDir\",\n                           \"The path to the meta data directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:MetaDataDir\\\"\"\n                       ],\n                       [\n                           \"Replace\",\n                           \"Instruct the cmdlet to replace an already existing model\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"The path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\ModelUtilImport\\\")\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Import a model into Dynamics 365 for Finance \\u0026 Operations\",\n        \"Name\":  \"Import-D365Model\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eImport-D365Model -Path c:\\\\temp\\\\d365fo.tools\\\\CustomModel.axmodel\\nThis will import the \\\"c:\\\\temp\\\\d365fo.tools\\\\CustomModel.axmodel\\\" model into the PackagesLocalDirectory location.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eImport-D365Model -Path c:\\\\temp\\\\d365fo.tools\\\\CustomModel.axmodel -Replace\\nThis will import the \\\"c:\\\\temp\\\\d365fo.tools\\\\CustomModel.axmodel\\\" model into the PackagesLocalDirectory location.\\r\\nIf the model already exists it will replace it.\",\n        \"Syntax\":  \"Import-D365Model [-Path] \\u003cString\\u003e [[-BinDir] \\u003cString\\u003e] [[-MetaDataDir] \\u003cString\\u003e] [-Replace] [-LogPath \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Import-D365RsatSelfServiceCertificates\",\n        \"Description\":  \"Import the certificates for RSAT into the correct stores and display the thumbprint\\n\\nWhen working with self-service environments you need to download a zip file from LCS. The zip file needs to be unblocked and then extracted into a folder, with only the .cer and the .pxf files inside\",\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the folder where the .cer and .pxf files are located\\nThe files needs to be extracted from the zip archive\",\n                           \"\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"Password\",\n                           \"Password for the .pxf file\\nWorking with self-service environments, the password will be displayed during the download of the zip archive\",\n                           \"\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Import certificates for RSAT\",\n        \"Name\":  \"Import-D365RsatSelfServiceCertificates\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eImport-D365RsatSelfServiceCertificates -Path \\\"C:\\\\Temp\\\\UAT\\\" -Password \\\"123456789\\\"\\nThis will import the .cer and .pxf files into the correct store, bases on the files located in \\\"C:\\\\Temp\\\\UAT\\\".\\r\\nAfter import it will display the thumbprint for both certificates.\\nSample output:\\r\\n[23:43:05][Import-D365RsatSelfServiceCertificates] Pfx Thumbprint:  B4D6921321434235463463414312343253523A05\\r\\n[23:43:05][Import-D365RsatSelfServiceCertificates] Cert Thumbprint: B4D6921321434235463463414312343253523A05\",\n        \"Syntax\":  \"Import-D365RsatSelfServiceCertificates [-Path] \\u003cString\\u003e [-Password] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Initialize-D365RsatCertificate\",\n        \"Description\":  \"Creates a new self signed certificate for automated testing and reconfigures the AOS Windows Identity Foundation configuration to trust the certificate\",\n        \"Tags\":  [\n                     \"Automated Test\",\n                     \"Test\",\n                     \"Regression\",\n                     \"Certificate\",\n                     \"Thumbprint\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"CertificateFileName\",\n                           \"Filename to be used when exporting the cer file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"(Join-Path $env:TEMP \\\"TestAuthCert.cer\\\")\"\n                       ],\n                       [\n                           \"PrivateKeyFileName\",\n                           \"Filename to be used when exporting the pfx file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"(Join-Path $env:TEMP \\\"TestAuthCert.pfx\\\")\"\n                       ],\n                       [\n                           \"Password\",\n                           \"The password that you want to use to protect your certificate with\\nThe default value is: \\\"Password1\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"(ConvertTo-SecureString -String \\\"Password1\\\" -Force -AsPlainText)\"\n                       ],\n                       [\n                           \"CertificateOnly\",\n                           \"Switch specifying if only the certificate needs to be created\\nIf specified, then only the certificate is created and the thumbprint is not added to the wif.config on the AOS side\\r\\nIf not specified (default) then the certificate is created and installed and the corresponding thumbprint is added to the wif.config on the local machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"KeepCertificateFile\",\n                           \"Instruct the cmdlet to copy the certificate file from the working directory into the desired location specified with OutputPath parameter\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the certificate file exported to, when using the KeepCertificateFile parameter switch\\nDefault value is: \\\"c:\\\\temp\\\\d365fo.tools\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ]\n                   ],\n        \"Alias\":  \"Initialize-D365TestAutomationCertificate\",\n        \"Author\":  \"Kenny Saelen (@kennysaelen)\",\n        \"Synopsis\":  \"Create and configure test automation certificate\",\n        \"Name\":  \"Initialize-D365RsatCertificate\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInitialize-D365RsatCertificate\\nThis will generate a certificate for issuer 127.0.0.1 and install it in the trusted root certificates and modify the wif.config of the AOS to include the thumbprint and trust the certificate.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInitialize-D365RsatCertificate -CertificateOnly\\nThis will generate a certificate for issuer 127.0.0.1 and install it in the trusted root certificates.\\r\\nNo actions will be taken regarding modifying the AOS wif.config file.\\nUse this when installing RSAT on a machine different from the AOS where RSAT is pointing to.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eInitialize-D365RsatCertificate -CertificateOnly -KeepCertificateFile\\nThis will generate a certificate for issuer 127.0.0.1 and install it in the trusted root certificates.\\r\\nNo actions will be taken regarding modifying the AOS wif.config file.\\r\\nThe pfx will be copied into the default \\\"c:\\\\temp\\\\d365fo.tools\\\" folder after creation.\\nUse this when installing RSAT on a machine different from the AOS where RSAT is pointing to.\\nThe pfx file enables you to import the same certificate across your entire network, instead of creating one per machine.\",\n        \"Syntax\":  \"Initialize-D365RsatCertificate [-CertificateFileName \\u003cString\\u003e] [-PrivateKeyFileName \\u003cString\\u003e] [-Password \\u003cSecureString\\u003e] [-CertificateOnly] [-KeepCertificateFile] [-OutputPath \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Install-D365SupportingSoftware\",\n        \"Description\":  \"Installs software commonly used when doing Dynamics 365 Finance and Operations development\\n\\nCommon ones: fiddler, postman, microsoft-edge, winmerge, notepadplusplus.install, azurepowershell, azure-cli, insomnia-rest-api-client, git.install\\n\\nFull list of software: https://community.chocolatey.org/packages\",\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"The name of the software to install\\nSupport a list of softwares that you want to have installed on the system\",\n                           \"SoftwareName\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Instruct the cmdlet to install the latest version of the software, regardless if it is already present on the system\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Dag Calafell (@dodiggitydag)\",\n        \"Synopsis\":  \"Install software supporting F\\u0026O development\",\n        \"Name\":  \"Install-D365SupportingSoftware\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInstall-D365SupportingSoftware -Name vscode\\nThis will install VSCode on the system.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInstall-D365SupportingSoftware -Name \\\"vscode\\\",\\\"fiddler\\\"\\nThis will install VSCode and fiddler on the system.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eInstall-D365SupportingSoftware -Name vscode -Force\\nThis will install VSCode on the system, forcing it to be (re)installed.\",\n        \"Syntax\":  \"Install-D365SupportingSoftware [-Name] \\u003cString[]\\u003e [-Force] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365AzCopyTransfer\",\n        \"Description\":  \"Transfer a file using the AzCopy tool\\n\\nYou can upload a local file to an Azure Storage Blob Container\\n\\nYou can download a file located in an Azure Storage Blob Container to a local folder\\n\\nYou can transfer a file located in an Azure Storage Blob Container to another Azure Storage Blob Container, across regions and subscriptions, if you have SAS tokens/keys as part of your uri\",\n        \"Tags\":  [\n                     \"Azure\",\n                     \"Azure Storage\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"Token\",\n                     \"Blob\",\n                     \"File\",\n                     \"Files\",\n                     \"Latest\",\n                     \"Bacpac\",\n                     \"Container\",\n                     \"LCS\",\n                     \"Asset\",\n                     \"Library\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"SourceUri\",\n                           \"Source file uri that you want to transfer\",\n                           \"FileLocation,SourceUrl\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"DestinationUri\",\n                           \"Destination file uri that you want to transfer the file to\",\n                           \"DestinationFile\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"FileName\",\n                           \"You might only pass a blob container or folder name in the DestinationUri parameter and want to give the transfered file another name than the original file name\",\n                           \"\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"DeleteOnTransferComplete\",\n                           \"Instruct the cmdlet to delete the source file when done transfering\\nDefault is $false which will leave the source file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"The path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\AzCopy\\\")\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Instruct the cmdlet to overwrite already existing file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Transfer a file using AzCopy\",\n        \"Name\":  \"Invoke-D365AzCopyTransfer\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365AzCopyTransfer -SourceUri \\\"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11\\u0026sr=...\\\" -DestinationUri \\\"c:\\\\temp\\\\d365fo.tools\\\\GOLDER.bacpac\\\"\\nThis will transfer a file from an Azure Storage Blob Container to a local folder/file on the machine.\\r\\nThe file that will be transfered/downloaded is SourceUri \\\"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11\\u0026sr=...\\\".\\r\\nThe file will be transfered/downloaded to DestinationUri \\\"c:\\\\temp\\\\d365fo.tools\\\\GOLDER.bacpac\\\".\\nIf there exists a file already, the file will NOT be overwritten.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365AzCopyTransfer -SourceUri \\\"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11\\u0026sr=...\\\" -DestinationUri \\\"c:\\\\temp\\\\d365fo.tools\\\\GOLDER.bacpac\\\" -Force\\nThis will transfer a file from an Azure Storage Blob Container to a local folder/file on the machine.\\r\\nThe file that will be transfered/downloaded is SourceUri \\\"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11\\u0026sr=...\\\".\\r\\nThe file will be transfered/downloaded to DestinationUri \\\"c:\\\\temp\\\\d365fo.tools\\\\GOLDER.bacpac\\\".\\r\\nIf there exists a file already, the file will  be overwritten, because Force has been supplied.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eInvoke-D365AzCopyTransfer -SourceUri \\\"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11\\u0026sr=...\\\" -DestinationUri \\r\\n\\\"https://456.blob.core.windows.net/targetcontainer/filename?sv=2015-12-11\\u0026sr=...\\\"\\nThis will transfer a file from an Azure Storage Blob Container to another Azure Storage Blob Container.\\r\\nThe file that will be transfered/downloaded is SourceUri \\\"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11\\u0026sr=...\\\".\\r\\nThe file will be transfered/downloaded to DestinationUri \\\"https://456.blob.core.windows.net/targetcontainer/filename?sv=2015-12-11\\u0026sr=...\\\".\\nFor this to work, you need to make sure both SourceUri and DestinationUri has an valid SAS token/key included.\\nIf there exists a file already, the file will NOT be overwritten.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eInvoke-D365AzCopyTransfer -SourceUri \\\"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11\\u0026sr=...\\\" -DestinationUri \\\"c:\\\\temp\\\\d365fo.tools\\\\GOLDER.bacpac\\\" \\r\\n-DeleteOnTransferComplete\\nThis will transfer a file from an Azure Storage Blob Container to a local folder/file on the machine.\\r\\nThe file that will be transfered/downloaded is SourceUri \\\"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11\\u0026sr=...\\\".\\r\\nThe file will be transfered/downloaded to DestinationUri \\\"c:\\\\temp\\\\d365fo.tools\\\\GOLDER.bacpac\\\".\\nAfter the file has been transfered to your local \\\"c:\\\\temp\\\\d365fo.tools\\\\GOLDER.bacpac\\\", it will be deleted from the SourceUri \\r\\n\\\"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11\\u0026sr=...\\\".\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003e$DestinationParms = Get-D365AzureStorageUrl -OutputAsHashtable\\nPS C:\\\\\\u003e $BlobFileDetails = Get-D365LcsDatabaseBackups -Latest | Invoke-D365AzCopyTransfer @DestinationParms\\r\\nPS C:\\\\\\u003e $BlobFileDetails | Invoke-D365AzCopyTransfer -DestinationUri \\\"C:\\\\Temp\\\" -DeleteOnTransferComplete\\nThis will transfer the lastest backup file from LCS Asset Library to your local \\\"C:\\\\Temp\\\".\\r\\nIt will get a destination Url, for it to transfer the backup file between the LCS storage account and your own.\\r\\nThe newly transfered file, that lives in your own storage account, will then be downloaded to your local \\\"c:\\\\Temp\\\".\\nAfter the file has been downloaded to your local \\\"C:\\\\Temp\\\", it will be deleted from your own storage account.\",\n        \"Syntax\":  \"Invoke-D365AzCopyTransfer [-SourceUri] \\u003cString\\u003e [-DestinationUri] \\u003cString\\u003e [[-FileName] \\u003cString\\u003e] [-DeleteOnTransferComplete] [[-LogPath] \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [-Force] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365AzureDevOpsNugetPush\",\n        \"Description\":  \"Push a package / nuget to an Azure DevOps feed\",\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the package / nuget that you want to push to the Azure DevOps feed\",\n                           \"PackagePath\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Source\",\n                           \"The logical name for the nuget source / connection that you want to use while pushing the package / nuget\\nThis requires you to register the nuget source, by hand, using the nuget.exe tool directly\\nBase command to use:\\r\\n.\\\\nuget sources add -Name \\\"D365FO\\\" -Source \\\"https://pkgs.dev.azure.com/Contoso/DynamicsFnO/_packaging/D365Packages/NuGet/v3/index.json\\\" -username \\\"alice@contoso.dk\\\" -password \\r\\n\\\"uVWw43FLzaWk9H2EDguXMVYD3DaWj3aHBL6bfZkc21cmkwoK8X78\\\"\\nPlease note that the password is in fact a personal access token and NOT your real password\\nThe value specified for Name in the nuget sources command, is the value to supply for Source for this cmdlet\",\n                           \"NugetSource,Destination\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"The path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\Nuget\\\")\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Push a package / nuget to Azure DevOps\",\n        \"Name\":  \"Invoke-D365AzureDevOpsNugetPush\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365AzureDevOpsNugetPush -Path \\\"c:\\\\temp\\\\d365fo.tools\\\\microsoft.dynamics.ax.application.devalm.buildxpp.10.0.605.10014.nupkg\\\" -Source \\\"Contoso\\\"\\nThis will push the package / nuget to the Azure DevOps feed.\\r\\nThe file that will be pushed / uploaded is identified by the Path \\\"c:\\\\temp\\\\d365fo.tools\\\\microsoft.dynamics.ax.application.devalm.buildxpp.10.0.605.10014.nupkg\\\".\\r\\nThe request will be going to the Azure DevOps instance that is registered with the Source (Name) \\\"Contoso\\\" via the nuget.exe tool.\",\n        \"Syntax\":  \"Invoke-D365AzureDevOpsNugetPush [[-Path] \\u003cString\\u003e] [[-Source] \\u003cString\\u003e] [[-LogPath] \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365AzureStorageDownload\",\n        \"Description\":  \"Download any file to an Azure Storage Account\",\n        \"Tags\":  [\n                     \"Azure\",\n                     \"Azure Storage\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"Token\",\n                     \"Blob\",\n                     \"File\",\n                     \"Files\",\n                     \"Latest\",\n                     \"Bacpac\",\n                     \"Container\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"AccountId\",\n                           \"Storage Account Name / Storage Account Id where you want to fetch the file from\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:AzureStorageAccountId\"\n                       ],\n                       [\n                           \"AccessToken\",\n                           \"The token that has the needed permissions for the download action\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:AzureStorageAccessToken\"\n                       ],\n                       [\n                           \"SAS\",\n                           \"The SAS key that you have created for the storage account or blob container\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:AzureStorageSAS\"\n                       ],\n                       [\n                           \"Container\",\n                           \"Name of the blob container inside the storage account you where the file is\",\n                           \"Blobname,Blob\",\n                           false,\n                           \"false\",\n                           \"$Script:AzureStorageContainer\"\n                       ],\n                       [\n                           \"FileName\",\n                           \"Name of the file that you want to download\",\n                           \"Name\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"Path\",\n                           \"Path to the folder / location you want to save the file\\nThe default path is \\\"c:\\\\temp\\\\d365fo.tools\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"Latest\",\n                           \"Instruct the cmdlet to download the latest file from Azure regardless of name\",\n                           \"GetLatest\",\n                           true,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Instruct the cmdlet to overwrite the local file if it already exists\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Download a file to Azure\",\n        \"Name\":  \"Invoke-D365AzureStorageDownload\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365AzureStorageDownload -AccountId \\\"miscfiles\\\" -AccessToken \\\"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\\\" -Container \\\"backupfiles\\\" -FileName \\\"OriginalUAT.bacpac\\\" -Path \\r\\n\\\"c:\\\\temp\\\"\\nWill download the \\\"OriginalUAT.bacpac\\\" file from the storage account and save it to \\\"c:\\\\temp\\\\OriginalUAT.bacpac\\\"\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365AzureStorageDownload -AccountId \\\"miscfiles\\\" -AccessToken \\\"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\\\" -Container \\\"backupfiles\\\" -Path \\\"c:\\\\temp\\\" -Latest\\nWill download the file with the latest modified datetime from the storage account and save it to \\\"c:\\\\temp\\\\\\\".\\r\\nThe complete path to the file will returned as output from the cmdlet.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003e$AzureParams = Get-D365ActiveAzureStorageConfig\\nPS C:\\\\\\u003e Invoke-D365AzureStorageDownload @AzureParams -Path \\\"c:\\\\temp\\\" -Latest\\nThis will get the current Azure Storage Account configuration details\\r\\nand use them as parameters to download the latest file from an Azure Storage Account\\nWill download the file with the latest modified datetime from the storage account and save it to \\\"c:\\\\temp\\\\\\\".\\r\\nThe complete path to the file will returned as output from the cmdlet.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eInvoke-D365AzureStorageDownload -Latest\\nThis will use the default parameter values that are based on the configuration stored inside \\\"Get-D365ActiveAzureStorageConfig\\\".\\r\\nWill download the file with the latest modified datetime from the storage account and save it to \\\"c:\\\\temp\\\\d365fo.tools\\\".\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eInvoke-D365AzureStorageDownload -AccountId \\\"miscfiles\\\" -SAS \\\"sv2018-03-28\\u0026siunlisted\\u0026src\\u0026sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\\\" -Container \\\"backupfiles\\\" -Path \\\"c:\\\\temp\\\" -Latest\\nWill download the file with the latest modified datetime from the storage account and save it to \\\"c:\\\\temp\\\\\\\".\\r\\nA SAS key is used to gain access to the container and downloading the file from it.\\r\\nThe complete path to the file will returned as output from the cmdlet.\",\n        \"Syntax\":  \"Invoke-D365AzureStorageDownload [-AccountId \\u003cString\\u003e] [-AccessToken \\u003cString\\u003e] [-SAS \\u003cString\\u003e] [-Container \\u003cString\\u003e] -FileName \\u003cString\\u003e [-Path \\u003cString\\u003e] [-Force] [-EnableException] [\\u003cCommonParameters\\u003e]\\nInvoke-D365AzureStorageDownload [-AccountId \\u003cString\\u003e] [-AccessToken \\u003cString\\u003e] [-SAS \\u003cString\\u003e] [-Container \\u003cString\\u003e] [-Path \\u003cString\\u003e] [-Latest] [-Force] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365AzureStorageUpload\",\n        \"Description\":  \"Upload any file to an Azure Storage Account\",\n        \"Tags\":  [\n                     \"Azure\",\n                     \"Azure Storage\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"Token\",\n                     \"Blob\",\n                     \"File\",\n                     \"Files\",\n                     \"Bacpac\",\n                     \"Container\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"AccountId\",\n                           \"Storage Account Name / Storage Account Id where you want to store the file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:AzureStorageAccountId\"\n                       ],\n                       [\n                           \"AccessToken\",\n                           \"The token that has the needed permissions for the upload action\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:AzureStorageAccessToken\"\n                       ],\n                       [\n                           \"SAS\",\n                           \"The SAS key that you have created for the storage account or blob container\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:AzureStorageSAS\"\n                       ],\n                       [\n                           \"Container\",\n                           \"Name of the blob container inside the storage account you want to store the file\",\n                           \"Blobname,Blob\",\n                           false,\n                           \"false\",\n                           \"$Script:AzureStorageContainer\"\n                       ],\n                       [\n                           \"Filepath\",\n                           \"Path to the file you want to upload\",\n                           \"Path,File\",\n                           true,\n                           \"true (ByValue)\",\n                           \"\"\n                       ],\n                       [\n                           \"ContentType\",\n                           \"Media type of the file that is going to be uploaded\\nThe value will be used for the blob property \\\"Content Type\\\".\\r\\nIf the parameter is left empty, the commandlet will try to automatically determined the value based on the file\\u0027s extension.\\r\\nIf the parameter is left empty and the value cannot be automatically be determined, Azure storage will automatically assign \\\"application/octet-stream\\\" as the content type.\\r\\nValid media type values can be found here: https://www.iana.org/assignments/media-types/media-types.xhtml\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Instruct the cmdlet to overwrite the file in the container if it already exists\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"DeleteOnUpload\",\n                           \"Switch to tell the cmdlet if you want the local file to be deleted after the upload completes\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Upload a file to Azure\",\n        \"Name\":  \"Invoke-D365AzureStorageUpload\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365AzureStorageUpload -AccountId \\\"miscfiles\\\" -AccessToken \\\"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\\\" -Container \\\"backupfiles\\\" -Filepath \\r\\n\\\"c:\\\\temp\\\\bacpac\\\\UAT_20180701.bacpac\\\" -DeleteOnUpload\\nThis will upload the \\\"c:\\\\temp\\\\bacpac\\\\UAT_20180701.bacpac\\\" up to the \\\"backupfiles\\\" container, inside the \\\"miscfiles\\\" Azure Storage Account that is access with the \\r\\n\\\"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\\\" token.\\r\\nAfter upload the local file will be deleted.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003e$AzureParams = Get-D365ActiveAzureStorageConfig\\nPS C:\\\\\\u003e New-D365Bacpac | Invoke-D365AzureStorageUpload @AzureParams\\nThis will get the current Azure Storage Account configuration details and use them as parameters to upload the file to an Azure Storage Account.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eNew-D365Bacpac | Invoke-D365AzureStorageUpload\\nThis will generate a new bacpac file using the \\\"New-D365Bacpac\\\" cmdlet.\\r\\nThe file will be uploaded to an Azure Storage Account using the \\\"Invoke-D365AzureStorageUpload\\\" cmdlet.\\r\\nThis will use the default parameter values that are based on the configuration stored inside \\\"Get-D365ActiveAzureStorageConfig\\\" for the \\\"Invoke-D365AzureStorageUpload\\\" cmdlet.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eInvoke-D365AzureStorageUpload -AccountId \\\"miscfiles\\\" -SAS \\\"sv2018-03-28\\u0026siunlisted\\u0026src\\u0026sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\\\" -Container \\\"backupfiles\\\" -Filepath \\r\\n\\\"c:\\\\temp\\\\bacpac\\\\UAT_20180701.bacpac\\\" -DeleteOnUpload\\nThis will upload the \\\"c:\\\\temp\\\\bacpac\\\\UAT_20180701.bacpac\\\" up to the \\\"backupfiles\\\" container, inside the \\\"miscfiles\\\" Azure Storage Account.\\r\\nA SAS key is used to gain access to the container and uploading the file to it.\",\n        \"Syntax\":  \"Invoke-D365AzureStorageUpload [-AccountId \\u003cString\\u003e] [-AccessToken \\u003cString\\u003e] [-SAS \\u003cString\\u003e] [-Container \\u003cString\\u003e] -Filepath \\u003cString\\u003e [-ContentType \\u003cString\\u003e] [-Force] [-DeleteOnUpload] [-EnableException] [\\u003cCommonParameters\\u003e]\\nInvoke-D365AzureStorageUpload [-AccountId \\u003cString\\u003e] [-AccessToken \\u003cString\\u003e] [-SAS \\u003cString\\u003e] [-Container \\u003cString\\u003e] -Filepath \\u003cString\\u003e [-ContentType \\u003cString\\u003e] [-Force] [-DeleteOnUpload] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365BestPractice\",\n        \"Description\":  \"Run the Best Practice checks against modules and models\",\n        \"Tags\":  [\n                     \"Best Practice\",\n                     \"BP\",\n                     \"BPs\",\n                     \"Module\",\n                     \"Model\",\n                     \"Quality\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Module\",\n                           \"Name of the Module to analyse\",\n                           \"ModuleName\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"Model\",\n                           \"Name of the Model to analyse\",\n                           \"ModelName\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the AOS service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:PackageDirectory\\\\bin\\\"\"\n                       ],\n                       [\n                           \"MetaDataDir\",\n                           \"The path to the meta data directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:MetaDataDir\\\"\"\n                       ],\n                       [\n                           \"PackagesRoot\",\n                           \"Instructs the cmdlet to use binary metadata\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"Path where you want to store the log outputs generated from the best practice analyser\\nAlso used as the path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\BestPractice\\\")\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"RunFixers\",\n                           \"Instructs the cmdlet to invoke the fixers for the identified warnings\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Gert Van Der Heyden (@gertvdheyden)\",\n        \"Synopsis\":  \"Run the Best Practice\",\n        \"Name\":  \"Invoke-D365BestPractice\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365BestPractice -module \\\"ApplicationSuite\\\" -model \\\"MyOverLayerModel\\\"\\nThis will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module.\\r\\nThe default output will be silenced.\\r\\nThe XML log file will be written to \\\"c:\\\\temp\\\\d365fo.tools\\\\ApplicationSuite\\\\Dynamics.AX.MyOverLayerModel.xppbp.xml\\\".\\r\\nThe log file will be written to \\\"c:\\\\temp\\\\d365fo.tools\\\\ApplicationSuite\\\\Dynamics.AX.MyOverLayerModel.xppbp.log\\\".\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365BestPractice -module \\\"ApplicationSuite\\\" -model \\\"MyOverLayerModel\\\" -PackagesRoot\\nThis will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module.\\r\\nWe use the binary metadata to look for the module and model.\\r\\nThe default output will be silenced.\\r\\nThe XML log file will be written to \\\"c:\\\\temp\\\\d365fo.tools\\\\ApplicationSuite\\\\Dynamics.AX.MyOverLayerModel.xppbp.xml\\\".\\r\\nThe log file will be written to \\\"c:\\\\temp\\\\d365fo.tools\\\\ApplicationSuite\\\\Dynamics.AX.MyOverLayerModel.xppbp.log\\\".\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eInvoke-D365BestPractice -module \\\"ApplicationSuite\\\" -model \\\"MyOverLayerModel\\\" -ShowOriginalProgress\\nThis will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module.\\r\\nThe output from the best practice check process will be written to the console / host.\\r\\nThe XML log file will be written to \\\"c:\\\\temp\\\\d365fo.tools\\\\ApplicationSuite\\\\Dynamics.AX.MyOverLayerModel.xppbp.xml\\\".\\r\\nThe log file will be written to \\\"c:\\\\temp\\\\d365fo.tools\\\\ApplicationSuite\\\\Dynamics.AX.MyOverLayerModel.xppbp.log\\\".\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eInvoke-D365BestPractice -module \\\"ApplicationSuite\\\" -model \\\"MyOverLayerModel\\\" -RunFixers\\nThis will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module.\\r\\nThe default output will be silenced.\\r\\nThe XML log file will be written to \\\"c:\\\\temp\\\\d365fo.tools\\\\ApplicationSuite\\\\Dynamics.AX.MyOverLayerModel.xppbp.xml\\\".\\r\\nThe log file will be written to \\\"c:\\\\temp\\\\d365fo.tools\\\\ApplicationSuite\\\\Dynamics.AX.MyOverLayerModel.xppbp.log\\\".\\r\\nInstructs the xppbp tool to run the fixers for all identified warnings.\",\n        \"Syntax\":  \"Invoke-D365BestPractice [-Module] \\u003cString\\u003e [-Model] \\u003cString\\u003e [[-BinDir] \\u003cString\\u003e] [[-MetaDataDir] \\u003cString\\u003e] [-PackagesRoot] [[-LogPath] \\u003cString\\u003e] [-ShowOriginalProgress] [-RunFixers] [-OutputCommandOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365CompilerResultAnalyzer\",\n        \"Description\":  \"Analyze the compiler output log and generate an excel file contain worksheets per type: Errors, Warnings, Tasks\\n\\nIt could be a Visual Studio compiler log or it could be a Invoke-D365ModuleCompile log you want analyzed\",\n        \"Tags\":  [\n                     \"Compiler\",\n                     \"Build\",\n                     \"Errors\",\n                     \"Warnings\",\n                     \"Tasks\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the compiler log file that you want to work against\\nA BuildModelResult.log or a Dynamics.AX.*.xppc.log file will both work\",\n                           \"LogFile\",\n                           true,\n                           \"true (ByValue, ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"OutputPath\",\n                           \"Path where you want the excel file (xlsx-file) saved to\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"SkipWarnings\",\n                           \"Instructs the cmdlet to skip warnings while analyzing the compiler output log file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"SkipTasks\",\n                           \"Instructs the cmdlet to skip tasks while analyzing the compiler output log file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nDefault path is the same as the AOS service \\\"PackagesLocalDirectory\\\" directory\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Analyze the compiler output log\",\n        \"Name\":  \"Invoke-D365CompilerResultAnalyzer\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365CompilerResultAnalyzer -Path \\\"c:\\\\temp\\\\d365fo.tools\\\\Custom\\\\Dynamics.AX.Custom.xppc.log\\\"\\nThis will analyse all compiler output log files generated from Visual Studio.\\r\\nIt will use the default path for the OutputPath parameter.\\nIt will build error and error summary worksheets.\\r\\nIt will build warning and warning summary worksheets.\\r\\nIt will build task and task summary worksheets.\\nA result set example:\\nFile                                                            Filename\\r\\n----                                                            --------\\r\\nc:\\\\temp\\\\d365fo.tools\\\\Custom-CompilerResults.xlsx                Custom-CompilerResults.xlsx\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365CompilerResultAnalyzer -Path \\\"c:\\\\temp\\\\d365fo.tools\\\\Custom\\\\Dynamics.AX.Custom.xppc.log\\\" -SkipWarnings\\nThis will analyse all compiler output log files generated from Visual Studio.\\r\\nIt will use the default path for the OutputPath parameter.\\nIt will build error and error summary worksheets.\\r\\nIt will build task and task summary worksheets.\\nA result set example:\\nFile                                                            Filename\\r\\n----                                                            --------\\r\\nc:\\\\temp\\\\d365fo.tools\\\\Custom-CompilerResults.xlsx                Custom-CompilerResults.xlsx\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eInvoke-D365CompilerResultAnalyzer -Path \\\"c:\\\\temp\\\\d365fo.tools\\\\Custom\\\\Dynamics.AX.Custom.xppc.log\\\" -SkipTasks\\nThis will analyse all compiler output log files generated from Visual Studio.\\r\\nIt will use the default path for the OutputPath parameter.\\nIt will build error and error summary worksheets.\\r\\nIt will build warning and warning summary worksheets.\\nA result set example:\\nFile                                                            Filename\\r\\n----                                                            --------\\r\\nc:\\\\temp\\\\d365fo.tools\\\\Custom-CompilerResults.xlsx                Custom-CompilerResults.xlsx\",\n        \"Syntax\":  \"Invoke-D365CompilerResultAnalyzer [-Path] \\u003cString\\u003e [[-OutputPath] \\u003cString\\u003e] [-SkipWarnings] [-SkipTasks] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365DataFlush\",\n        \"Description\":  \"Invoke one of the runnable classes that is clearing cache, data or something else\",\n        \"Tags\":  [\n                     \"Flush\",\n                     \"Url\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Url\",\n                           \"URL to the Dynamics 365 instance you want to clear the AOD cache on\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Class\",\n                           \"The class that you want to execute.\\nDefault value is \\\"SysFlushAod\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"SysFlushAod\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Invoke the one of the data flush classes\",\n        \"Name\":  \"Invoke-D365DataFlush\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365DataFlush\\nThis will make a call against the default URL for the machine and\\r\\nhave it execute the SysFlushAOD class.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365DataFlush -Class SysFlushData,SysFlushAod\\nThis will make a call against the default URL for the machine and\\r\\nhave it execute the SysFlushData and SysFlushAod classes.\",\n        \"Syntax\":  \"Invoke-D365DataFlush [[-Url] \\u003cString\\u003e] [-Class \\u003cString[]\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365DbSync\",\n        \"Description\":  \"Uses the sync.exe (engine) to synchronize the database for the environment\",\n        \"Tags\":  [\n                     \"Database\",\n                     \"Sync\",\n                     \"SyncDB\",\n                     \"Synchronization\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"BinDirTools\",\n                           \"Path to where the tools on the machine can be found\\nDefault value is normally the AOS Service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:BinDirTools\"\n                       ],\n                       [\n                           \"MetadataDir\",\n                           \"Path to where the tools on the machine can be found\\nDefault value is normally the AOS Service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"SyncMode\",\n                           \"The sync mode the sync engine will use\\nDefault value is: \\\"FullAll\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"FullAll\"\n                       ],\n                       [\n                           \"Verbosity\",\n                           \"Parameter used to instruct the level of verbosity the sync engine has to report back\\nDefault value is: \\\"Normal\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"Normal\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"The path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\DbSync\\\")\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Rasmus Andersen (@ITRasmus)\",\n        \"Synopsis\":  \"Invoke the synchronization process used in Visual Studio\",\n        \"Name\":  \"Invoke-D365DbSync\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365DBSync\\nThis will invoke the sync engine and have it work against the database.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365DBSync -Verbose\\nThis will invoke the sync engine and have it work against the database. It will output the same level of details that Visual Studio would normally do.\",\n        \"Syntax\":  \"Invoke-D365DbSync [[-BinDirTools] \\u003cString\\u003e] [[-MetadataDir] \\u003cString\\u003e] [[-SyncMode] \\u003cString\\u003e] [[-Verbosity] \\u003cString\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [[-LogPath] \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365DbSyncModule\",\n        \"Description\":  \"Retrieve the list of installed packages / modules where the name fits the ModelName parameter.\\n\\nIt will run loop over the list and start the sync process against all tables, views, data entities, table-extensions,\\nview-extensions and data entities-extensions of every iterated model\",\n        \"Tags\":  [\n                     \"Database\",\n                     \"Sync\",\n                     \"SyncDB\",\n                     \"Synchronization\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Module\",\n                           \"Name of the model you want to sync tables and table extensions\\nSupports an array of module names\",\n                           \"ModuleName\",\n                           true,\n                           \"true (ByValue, ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"Verbosity\",\n                           \"Parameter used to instruct the level of verbosity the sync engine has to report back\\nDefault value is: \\\"Normal\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"Normal\"\n                       ],\n                       [\n                           \"BinDirTools\",\n                           \"Path to where the tools on the machine can be found\\nDefault value is normally the AOS Service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:BinDirTools\"\n                       ],\n                       [\n                           \"MetadataDir\",\n                           \"Path to where the tools on the machine can be found\\nDefault value is normally the AOS Service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"The path where the log file will be saved\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\DbSync\\\")\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Jasper Callens - Cegeka\",\n        \"Synopsis\":  \"Synchronize all sync base and extension elements based on a modulename\",\n        \"Name\":  \"Invoke-D365DbSyncModule\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365DbSyncModule -Module \\\"MyModel1\\\"\\nIt will start the sync process against all tables, views, data entities, table-extensions, view-extensions and data entities-extensions of MyModel1.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365DbSyncModule -Module \\\"MyModel1\\\",\\\"MyModel2\\\"\\nIt will run loop over the list and start the sync process against all tables, views, data entities, table-extensions, view-extensions and data entities-extensions of every iterated model.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365Module -Name \\\"MyModel*\\\" | Invoke-D365DbSyncModule\\nRetrieve the list of installed packages / modules where the name fits the search \\\"MyModel*\\\".\\nThe result is:\\r\\nMyModel1\\r\\nMyModel2\\nIt will run loop over the list and start the sync process against all tables, views, data entities, table-extensions, view-extensions and data entities-extensions of every iterated model.\",\n        \"Syntax\":  \"Invoke-D365DbSyncModule [-Module] \\u003cString[]\\u003e [[-Verbosity] \\u003cString\\u003e] [[-BinDirTools] \\u003cString\\u003e] [[-MetadataDir] \\u003cString\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [[-LogPath] \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365DbSyncPartial\",\n        \"Description\":  \"Uses the sync.exe (engine) to synchronize the database for the environment\",\n        \"Tags\":  [\n                     \"Database\",\n                     \"Sync\",\n                     \"SyncDB\",\n                     \"Synchronization\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"SyncList\",\n                           \"The list of objects that you want to pass on to the database synchronoziation engine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"SyncExtensionsList\",\n                           \"The list of extension objects that you want to pass on to the database synchronoziation engine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"SyncMode\",\n                           \"The sync mode the sync engine will use\\nDefault value is: \\\"PartialList\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"PartialList\"\n                       ],\n                       [\n                           \"Verbosity\",\n                           \"Parameter used to instruct the level of verbosity the sync engine has to report back\\nDefault value is: \\\"Normal\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"Normal\"\n                       ],\n                       [\n                           \"BinDirTools\",\n                           \"Path to where the tools on the machine can be found\\nDefault value is normally the AOS Service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:BinDirTools\"\n                       ],\n                       [\n                           \"MetadataDir\",\n                           \"Path to where the tools on the machine can be found\\nDefault value is normally the AOS Service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"The path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\DbSync\\\")\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Invoke the synchronization process used in Visual Studio\",\n        \"Name\":  \"Invoke-D365DbSyncPartial\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365DBSyncPartial -SyncList \\\"CustCustomerEntity\\\",\\\"SalesTable\\\"\\nThis will invoke the sync engine and have it work against the database.\\r\\nIt will run with the default value \\\"PartialList\\\" as the SyncMode.\\r\\nIt will run the sync process against \\\"CustCustomerEntity\\\" and \\\"SalesTable\\\"\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365DBSyncPartial -SyncList \\\"CustCustomerEntity\\\",\\\"SalesTable\\\" -Verbose\\nThis will invoke the sync engine and have it work against the database.\\r\\nIt will run with the default value \\\"PartialList\\\" as the SyncMode.\\r\\nIt will run the sync process against \\\"CustCustomerEntity\\\" and \\\"SalesTable\\\"\\nIt will output the same level of details that Visual Studio would normally do.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eInvoke-D365DBSyncPartial -SyncList \\\"CustCustomerEntity\\\",\\\"SalesTable\\\" -SyncExtensionsList \\\"CaseLog.Extension\\\",\\\"CategoryTable.Extension\\\" -Verbose\\nThis will invoke the sync engine and have it work against the database.\\r\\nIt will run with the default value \\\"PartialList\\\" as the SyncMode.\\r\\nIt will run the sync process against \\\"CustCustomerEntity\\\", \\\"SalesTable\\\", \\\"CaseLog.Extension\\\" and \\\"CategoryTable.Extension\\\"\\nIt will output the same level of details that Visual Studio would normally do.\",\n        \"Syntax\":  \"Invoke-D365DbSyncPartial [[-SyncList] \\u003cString[]\\u003e] [[-SyncExtensionsList] \\u003cString[]\\u003e] [[-SyncMode] \\u003cString\\u003e] [[-Verbosity] \\u003cString\\u003e] [[-BinDirTools] \\u003cString\\u003e] [[-MetadataDir] \\u003cString\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [[-LogPath] \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365GenerateReportAggregateDataEntity\",\n        \"Description\":  \"Traverse the Dynamics 365 Finance \\u0026 Operations code repository for all Aggregate Data Entities and generate a metadata report\",\n        \"Tags\":  [\n                     \"Metadata\",\n                     \"Report\",\n                     \"Documentation\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the report file to be saved\\nThe default value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Generate Report for Aggregate Data Entity\",\n        \"Name\":  \"Invoke-D365GenerateReportAggregateDataEntity\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365GenerateReportAggregateDataEntity\\nThis will generate a report.\\r\\nIt will contain all the metadata and save it into a xlsx (Excel) file.\\r\\nIt will saved the file to \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n        \"Syntax\":  \"Invoke-D365GenerateReportAggregateDataEntity [[-OutputPath] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365GenerateReportAggregateMeasure\",\n        \"Description\":  \"Traverse the Dynamics 365 Finance \\u0026 Operations code repository for all Aggregate Measures and generate a metadata report\",\n        \"Tags\":  [\n                     \"Metadata\",\n                     \"Report\",\n                     \"Documentation\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the report file to be saved\\nThe default value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Generate Report for Aggregate Measure\",\n        \"Name\":  \"Invoke-D365GenerateReportAggregateMeasure\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365GenerateReportAggregateMeasure\\nThis will generate a report.\\r\\nIt will contain all the metadata and save it into a xlsx (Excel) file.\\r\\nIt will saved the file to \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n        \"Syntax\":  \"Invoke-D365GenerateReportAggregateMeasure [[-OutputPath] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365GenerateReportConfigKey\",\n        \"Description\":  \"Traverse the Dynamics 365 Finance \\u0026 Operations code repository for all Config Keys and generate a metadata report\",\n        \"Tags\":  [\n                     \"Metadata\",\n                     \"Report\",\n                     \"Documentation\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the report file to be saved\\nThe default value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Generate Report for Config Key\",\n        \"Name\":  \"Invoke-D365GenerateReportConfigKey\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365GenerateReportConfigKey\\nThis will generate a report.\\r\\nIt will contain all the metadata and save it into a xlsx (Excel) file.\\r\\nIt will saved the file to \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n        \"Syntax\":  \"Invoke-D365GenerateReportConfigKey [[-OutputPath] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365GenerateReportConfigKeyGroup\",\n        \"Description\":  \"Traverse the Dynamics 365 Finance \\u0026 Operations code repository for all Config Key Groups and generate a metadata report\",\n        \"Tags\":  [\n                     \"Metadata\",\n                     \"Report\",\n                     \"Documentation\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the report file to be saved\\nThe default value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Generate Report for Config Key Group\",\n        \"Name\":  \"Invoke-D365GenerateReportConfigKeyGroup\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365GenerateReportConfigKeyGroup\\nThis will generate a report.\\r\\nIt will contain all the metadata and save it into a xlsx (Excel) file.\\r\\nIt will saved the file to \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n        \"Syntax\":  \"Invoke-D365GenerateReportConfigKeyGroup [[-OutputPath] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365GenerateReportDataEntity\",\n        \"Description\":  \"Traverse the Dynamics 365 Finance \\u0026 Operations code repository for all Data Entities and generate a metadata report\",\n        \"Tags\":  [\n                     \"Metadata\",\n                     \"Report\",\n                     \"Documentation\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the report file to be saved\\nThe default value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Generate Report for Data Entity\",\n        \"Name\":  \"Invoke-D365GenerateReportDataEntity\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365GenerateReportDataEntity\\nThis will generate a report.\\r\\nIt will contain all the metadata and save it into a xlsx (Excel) file.\\r\\nIt will saved the file to \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n        \"Syntax\":  \"Invoke-D365GenerateReportDataEntity [[-OutputPath] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365GenerateReportDataEntityField\",\n        \"Description\":  \"Traverse the Dynamics 365 Finance \\u0026 Operations code repository for all Data Entities with their fields and generate a metadata report\",\n        \"Tags\":  [\n                     \"Metadata\",\n                     \"Report\",\n                     \"Documentation\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the report file to be saved\\nThe default value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Generate Report for Data Entity with fields\",\n        \"Name\":  \"Invoke-D365GenerateReportDataEntityField\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365GenerateReportDataEntityField\\nThis will generate a report.\\r\\nIt will contain all the metadata and save it into a xlsx (Excel) file.\\r\\nIt will saved the file to \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n        \"Syntax\":  \"Invoke-D365GenerateReportDataEntityField [[-OutputPath] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365GenerateReportKpi\",\n        \"Description\":  \"Traverse the Dynamics 365 Finance \\u0026 Operations code repository for all KPIs and generate a metadata report\",\n        \"Tags\":  [\n                     \"Metadata\",\n                     \"Report\",\n                     \"Documentation\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the report file to be saved\\nThe default value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Generate Report for KPI\",\n        \"Name\":  \"Invoke-D365GenerateReportKpi\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365GenerateReportKpi\\nThis will generate a report.\\r\\nIt will contain all the metadata and save it into a xlsx (Excel) file.\\r\\nIt will saved the file to \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n        \"Syntax\":  \"Invoke-D365GenerateReportKpi [[-OutputPath] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365GenerateReportLicenseCode\",\n        \"Description\":  \"Traverse the Dynamics 365 Finance \\u0026 Operations code repository for all License Codes and generate a metadata report\",\n        \"Tags\":  [\n                     \"Metadata\",\n                     \"Report\",\n                     \"Documentation\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the report file to be saved\\nThe default value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Generate Report for License Code\",\n        \"Name\":  \"Invoke-D365GenerateReportLicenseCode\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365GenerateReportLicenseCode\\nThis will generate a report.\\r\\nIt will contain all the metadata and save it into a xlsx (Excel) file.\\r\\nIt will saved the file to \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n        \"Syntax\":  \"Invoke-D365GenerateReportLicenseCode [[-OutputPath] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365GenerateReportMenuItem\",\n        \"Description\":  \"Traverse the Dynamics 365 Finance \\u0026 Operations code repository for all types of Menu Items and generate a metadata report\",\n        \"Tags\":  [\n                     \"Metadata\",\n                     \"Report\",\n                     \"Documentation\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the report file to be saved\\nThe default value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Generate Report for Menu Item\",\n        \"Name\":  \"Invoke-D365GenerateReportMenuItem\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365GenerateReportMenuItem\\nThis will generate a report.\\r\\nIt will contain all the metadata and save it into a xlsx (Excel) file.\\r\\nIt will saved the file to \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n        \"Syntax\":  \"Invoke-D365GenerateReportMenuItem [[-OutputPath] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365GenerateReports\",\n        \"Description\":  \"Traverse the Dynamics 365 Finance \\u0026 Operations code repository for all related objects and generate a metadata report for each\",\n        \"Tags\":  [\n                     \"Metadata\",\n                     \"Report\",\n                     \"Documentation\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the report file to be saved\\nThe default value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Generate Report for all related objects\",\n        \"Name\":  \"Invoke-D365GenerateReports\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365GenerateReports\\nThis will generate a report for each related object.\\r\\nIt will contain all the metadata and save it into a xlsx (Excel) file.\\r\\nIt will saved the file to \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n        \"Syntax\":  \"Invoke-D365GenerateReports [[-OutputPath] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365GenerateReportSsrs\",\n        \"Description\":  \"Traverse the Dynamics 365 Finance \\u0026 Operations code repository for all SSRS Reports and generate a metadata report\",\n        \"Tags\":  [\n                     \"Metadata\",\n                     \"Report\",\n                     \"Documentation\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the report file to be saved\\nThe default value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Generate Report for SSRS Report\",\n        \"Name\":  \"Invoke-D365GenerateReportSsrs\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365GenerateReportSsrs\\nThis will generate a report.\\r\\nIt will contain all the metadata and save it into a xlsx (Excel) file.\\r\\nIt will saved the file to \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n        \"Syntax\":  \"Invoke-D365GenerateReportSsrs [[-OutputPath] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365GenerateReportTable\",\n        \"Description\":  \"Traverse the Dynamics 365 Finance \\u0026 Operations code repository for all Tables and generate a metadata report\",\n        \"Tags\":  [\n                     \"Metadata\",\n                     \"Report\",\n                     \"Documentation\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the report file to be saved\\nThe default value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Generate Report for Table\",\n        \"Name\":  \"Invoke-D365GenerateReportTable\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365GenerateReportTable\\nThis will generate a report.\\r\\nIt will contain all the metadata and save it into a xlsx (Excel) file.\\r\\nIt will saved the file to \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n        \"Syntax\":  \"Invoke-D365GenerateReportTable [[-OutputPath] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365GenerateReportWorkflowType\",\n        \"Description\":  \"Traverse the Dynamics 365 Finance \\u0026 Operations code repository for all Workflow Types and generate a metadata report\",\n        \"Tags\":  [\n                     \"Metadata\",\n                     \"Report\",\n                     \"Documentation\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the report file to be saved\\nThe default value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nNormally it is located under the AOSService directory in \\\"PackagesLocalDirectory\\\"\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Generate Report for Workflow Type\",\n        \"Name\":  \"Invoke-D365GenerateReportWorkflowType\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365GenerateReportWorkflowType\\nThis will generate a report.\\r\\nIt will contain all the metadata and save it into a xlsx (Excel) file.\\r\\nIt will saved the file to \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n        \"Syntax\":  \"Invoke-D365GenerateReportWorkflowType [[-OutputPath] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365InstallAzCopy\",\n        \"Description\":  \"Download and extract the AzCopy.exe to your machine\",\n        \"Params\":  [\n                       [\n                           \"Url\",\n                           \"Url/Uri to where the latest AzCopy download is located\\nThe default value is for v10 as of writing\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"https://aka.ms/downloadazcopy-v10-windows\"\n                       ],\n                       [\n                           \"Path\",\n                           \"Path to where you want the AzCopy to be extracted to\\nDefault value is: \\\"C:\\\\temp\\\\d365fo.tools\\\\AzCopy\\\\AzCopy.exe\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"C:\\\\temp\\\\d365fo.tools\\\\AzCopy\\\\AzCopy.exe\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Download AzCopy.exe to your machine\",\n        \"Name\":  \"Invoke-D365InstallAzCopy\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365InstallAzCopy -Path \\\"C:\\\\temp\\\\d365fo.tools\\\\AzCopy\\\\AzCopy.exe\\\"\\nThis will update the path for the AzCopy.exe in the modules configuration\",\n        \"Syntax\":  \"Invoke-D365InstallAzCopy [[-Url] \\u003cString\\u003e] [[-Path] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365InstallLicense\",\n        \"Description\":  \"Install a license for a 3. party solution using the builtin \\\"Microsoft.Dynamics.AX.Deployment.Setup.exe\\\" executable\",\n        \"Tags\":  [\n                     \"License\",\n                     \"Install\",\n                     \"ISV\",\n                     \"3. Party\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the license file\",\n                           \"File\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"MetaDataDir\",\n                           \"The path to the meta data directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:MetaDataDir\\\"\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\"\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"The path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\InstallLicense\\\")\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@splaxi)\",\n        \"Synopsis\":  \"Install a license for a 3. party solution\",\n        \"Name\":  \"Invoke-D365InstallLicense\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365InstallLicense -Path c:\\\\temp\\\\d365fo.tools\\\\license.txt\\nThis will use the default paths and start the Microsoft.Dynamics.AX.Deployment.Setup.exe with the needed parameters to import / install the license file.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365InstallLicense -Path c:\\\\temp\\\\d365fo.tools\\\\license.txt -ShowOriginalProgress\\nThis will use the default paths and start the Microsoft.Dynamics.AX.Deployment.Setup.exe with the needed parameters to import / install the license file.\\r\\nThe output from the installation process will be written to the console / host.\",\n        \"Syntax\":  \"Invoke-D365InstallLicense [-Path] \\u003cString\\u003e [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [[-MetaDataDir] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-LogPath] \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365InstallNuget\",\n        \"Description\":  \"Download the nuget.exe to your machine\\n\\nBy default it will download the latest version\",\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to where you want the nuget.exe to be downloaded to\\nDefault value is: \\\"C:\\\\temp\\\\d365fo.tools\\\\nuget\\\\nuget.exe\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"C:\\\\temp\\\\d365fo.tools\\\\nuget\"\n                       ],\n                       [\n                           \"Url\",\n                           \"Url/Uri to where the latest nuget download is located\\nThe default value is \\\"https://dist.nuget.org/win-x86-commandline/latest/nuget.exe\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"https://dist.nuget.org/win-x86-commandline/latest/nuget.exe\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Download nuget.exe to your machine\",\n        \"Name\":  \"Invoke-D365InstallNuget\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365InstallNuget\\nThis will download the latest version of nuget.\\r\\nThe install path is identified by the default value: \\\"C:\\\\temp\\\\d365fo.tools\\\\nuget\\\\nuget.exe\\\".\",\n        \"Syntax\":  \"Invoke-D365InstallNuget [[-Path] \\u003cString\\u003e] [[-Url] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365InstallSqlPackage\",\n        \"Description\":  \"Download and extract SqlPackage.exe to your machine.\",\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to where you want the SqlPackage to be extracted to\\nDefault value is: \\\"C:\\\\temp\\\\d365fo.tools\\\\SqlPackage\\\\SqlPackage.exe\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"C:\\\\temp\\\\d365fo.tools\\\\SqlPackage\"\n                       ],\n                       [\n                           \"Latest\",\n                           \"Overrides the Url parameter and uses the latest download URL provided by the evergreen link https://aka.ms/sqlpackage-windows\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Url\",\n                           \"Url/Uri to where the SqlPackage download is located\\nThe default value is for version 162.2.111.2 as of writing.\\nFurther discussion can be found here: https://github.com/d365collaborative/d365fo.tools/discussions/816\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"https://go.microsoft.com/fwlink/?linkid=2261576\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Download SqlPackage.exe to your machine\",\n        \"Name\":  \"Invoke-D365InstallSqlPackage\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365InstallSqlPackage\\nThis will download and extract SqlPackage.exe.\\r\\nIt will use the default value for the Path parameter, for where to save the SqlPackage.exe.\\r\\nIt will update the path for the SqlPackage.exe in configuration.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365InstallSqlPackage -Path \\\"C:\\\\temp\\\\SqlPackage\\\"\\nThis will download and extract SqlPackage.exe.\\r\\nIt will save the SqlPackage.exe to \\\"C:\\\\temp\\\\SqlPackage\\\".\\r\\nIt will update the path for the SqlPackage.exe in configuration.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eInvoke-D365InstallSqlPackage -Latest\\nThis will download and extract the latest SqlPackage.exe.\\r\\nIt will use https://aka.ms/sqlpackage-windows as the download URL.\\r\\nIt will update the path for the SqlPackage.exe in configuration.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eInvoke-D365InstallSqlPackage -Url \\\"https://go.microsoft.com/fwlink/?linkid=3030303\\\"\\nThis will download and extract SqlPackage.exe.\\r\\nIt will rely on the Url parameter to base the download on.\\r\\nIt will use the \\\"https://go.microsoft.com/fwlink/?linkid=3030303\\\" as value for the Url parameter.\\r\\nIt will update the path for the SqlPackage.exe in configuration.\",\n        \"Syntax\":  \"Invoke-D365InstallSqlPackage [-Path \\u003cString\\u003e] [-Url \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\\nInvoke-D365InstallSqlPackage [-Path \\u003cString\\u003e] [-Latest] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365LcsApiRefreshToken\",\n        \"Description\":  \"Invoke the refresh logic that refreshes the token object based on the ClientId and RefreshToken\",\n        \"Tags\":  [\n                     \"LCS\",\n                     \"API\",\n                     \"Token\",\n                     \"BearerToken\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"ClientId\",\n                           \"The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"RefreshToken\",\n                           \"The Refresh Token that you want to use for the authentication process\",\n                           \"Token,refresh_token\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"InputObject\",\n                           \"The entire object that you received from the Get-D365LcsApiToken command, which contains the needed RefreshToken\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Refresh the token for lcs communication\",\n        \"Name\":  \"Invoke-D365LcsApiRefreshToken\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsApiRefreshToken -ClientId \\\"9b4f4503-b970-4ade-abc6-2c086e4c4929\\\" -RefreshToken \\\"Tsdljfasfe2j32324\\\"\\nThis will refresh an OAuth 2.0 access token, and obtain a (new) valid OAuth 2.0 access token from Azure Active Directory.\\r\\nThe ClientId \\\"9b4f4503-b970-4ade-abc6-2c086e4c4929\\\" is used in the OAuth 2.0 \\\"Refresh Token\\\" Grant Flow to authenticate.\\r\\nThe RefreshToken \\\"Tsdljfasfe2j32324\\\" is used to prove to Azure Active Directoy that we are allowed to obtain a new valid Access Token.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003e$temp = Get-D365LcsApiToken -LcsApiUri \\\"https://lcsapi.eu.lcs.dynamics.com\\\" -ClientId \\\"9b4f4503-b970-4ade-abc6-2c086e4c4929\\\" -Username \\\"serviceaccount@domain.com\\\" -Password \\\"TopSecretPassword\\\"\\nPS C:\\\\\\u003e $temp = Invoke-D365LcsApiRefreshToken -ClientId \\\"9b4f4503-b970-4ade-abc6-2c086e4c4929\\\" -InputObject $temp\\nThis will refresh an OAuth 2.0 access token, and obtain a (new) valid OAuth 2.0 access token from Azure Active Directory.\\r\\nThis will obtain a new token object from the Get-D365LcsApiToken cmdlet and store it in $temp.\\r\\nThen it will pass $temp to the Invoke-D365LcsApiRefreshToken along with the ClientId \\\"9b4f4503-b970-4ade-abc6-2c086e4c4929\\\".\\r\\nThe new token object will be save into $temp.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsApiConfig | Invoke-D365LcsApiRefreshToken | Set-D365LcsApiConfig\\nThis will refresh an OAuth 2.0 access token, and obtain a (new) valid OAuth 2.0 access token from Azure Active Directory.\\r\\nThis will fetch the current LCS API details from Get-D365LcsApiConfig.\\r\\nThe output from Get-D365LcsApiConfig is piped directly to Invoke-D365LcsApiRefreshToken, which will fetch a new token object.\\r\\nThe new token object is piped directly into Set-D365LcsApiConfig, which will save the needed details into the configuration store.\",\n        \"Syntax\":  \"Invoke-D365LcsApiRefreshToken -ClientId \\u003cString\\u003e [-InputObject \\u003cPSObject\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\\nInvoke-D365LcsApiRefreshToken -ClientId \\u003cString\\u003e -RefreshToken \\u003cString\\u003e [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365LcsDatabaseExport\",\n        \"Description\":  \"Start a database export from an environment from a LCS project\",\n        \"Tags\":  [\n                     \"Environment\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"LCS\",\n                     \"Database backup\",\n                     \"Api\",\n                     \"Backup\",\n                     \"Bacpac\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiProjectId\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"Token\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiBearerToken\"\n                       ],\n                       [\n                           \"SourceEnvironmentId\",\n                           \"The unique id of the environment that you want to use as the source for the database export\\nThe Id can be located inside the LCS portal\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"BackupName\",\n                           \"Name of the backup file when it is being exported from the environment\\nThe file shouldn\\u0027t contain any extension at all, just the desired file name\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"SkipInitialStatusFetch\",\n                           \"Instruct the cmdlet to skip the first fetch of the database refresh status\\nUseful when you have a large script that handles this status validation and you don\\u0027t want to spend time with this cmdlet\\nDefault output from this cmdlet is 2 (two) different objects. The first object is the response object for starting the export operation. The second object is the response object from fetching the \\r\\nstatus of the export operation.\\nSetting this parameter (activate it), will affect the number of output objects. If you skip, only the first response object outputted.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"FailOnErrorMessage\",\n                           \"Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\\r\\nThis allows you to implement custom retry / error handling logic\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"RetryTimeout\",\n                           \"The retry timeout, before the cmdlet should quit retrying based on the 429 status code\\nNeeds to be provided in the timspan notation:\\r\\n\\\"hh:mm:ss\\\"\\nhh is the number of hours, numerical notation only\\r\\nmm is the number of minutes\\r\\nss is the numbers of seconds\\nEach section of the timeout has to valid, e.g.\\r\\nhh can maximum be 23\\r\\nmm can maximum be 59\\r\\nss can maximum be 59\\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"00:00:00\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Start a database export from an environment\",\n        \"Name\":  \"Invoke-D365LcsDatabaseExport\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsDatabaseExport -ProjectId 123456789 -SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -BackupName \\\"BackupViaApi\\\" -BearerToken \\\"JldjfafLJdfjlfsalfd...\\\" -LcsApiUri \\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\nThis will start the database export from the Source environment.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe source environment is identified by the SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which can be obtained in the LCS portal.\\r\\nThe backup name is identified by the BackupName \\\"BackupViaApi\\\", which instructs the API to save the backup with that filename.\\r\\nThe request will authenticate with the BearerToken \\\"JldjfafLJdfjlfsalfd...\\\".\\r\\nThe http request will be going to the LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\" (NON-EUROPE).\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsDatabaseExport -SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -BackupName \\\"BackupViaApi\\\"\\nThis will start the database export from the Source environment.\\r\\nThe source environment is identified by the SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which can be obtained in the LCS portal.\\r\\nThe backup name is identified by the BackupName \\\"BackupViaApi\\\", which instructs the API to save the backup with that filename.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003e$databaseExport = Invoke-D365LcsDatabaseExport -SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -BackupName \\\"BackupViaApi\\\" -SkipInitialStatusFetch\\nPS C:\\\\\\u003e $databaseExport | Get-D365LcsDatabaseOperationStatus -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e9\\\" -SleepInSeconds 60\\nThis will start the database export from the Source environment.\\r\\nThe source environment is identified by the SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which can be obtained in the LCS portal.\\r\\nThe backup name is identified by the BackupName \\\"BackupViaApi\\\", which instructs the API to save the backup with that filename.\\r\\nIt will skip the first database operation status fetch and only output the details from starting the export.\\nThe output from Invoke-D365LcsDatabaseExport is stored in the $databaseExport. This will enable you to pass the $databaseExport variable to other cmdlets which should make things easier for you.\\nWill pipe the $databaseExport variable to the Get-D365LcsDatabaseOperationStatus cmdlet and get the status from the database export job.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsDatabaseExport -SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -BackupName \\\"BackupViaApi\\\" -SkipInitialStatusFetch\\nThis will start the database export from the Source environment.\\r\\nThe source environment is identified by the SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which can be obtained in the LCS portal.\\r\\nThe backup name is identified by the BackupName \\\"BackupViaApi\\\", which instructs the API to save the backup with that filename.\\r\\nIt will skip the first database operation status fetch and only output the details from starting the export.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsDatabaseExport -SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -BackupName \\\"BackupViaApi\\\" -RetryTimeout \\\"00:01:00\\\"\\nThis will start the database export from the Source environment, and allow for the cmdlet to retry for no more than 1 minute.\\r\\nThe source environment is identified by the SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which can be obtained in the LCS portal.\\r\\nThe backup name is identified by the BackupName \\\"BackupViaApi\\\", which instructs the API to save the backup with that filename.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\",\n        \"Syntax\":  \"Invoke-D365LcsDatabaseExport [[-ProjectId] \\u003cInt32\\u003e] [[-BearerToken] \\u003cString\\u003e] [-SourceEnvironmentId] \\u003cString\\u003e [-BackupName] \\u003cString\\u003e [[-LcsApiUri] \\u003cString\\u003e] [-SkipInitialStatusFetch] [-FailOnErrorMessage] [[-RetryTimeout] \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365LcsDatabaseRefresh\",\n        \"Description\":  \"Start a database refresh between 2 environments from a LCS project\",\n        \"Tags\":  [\n                     \"Environment\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"LCS\",\n                     \"Database backup\",\n                     \"Api\",\n                     \"Backup\",\n                     \"Restore\",\n                     \"Refresh\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiProjectId\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"Token\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiBearerToken\"\n                       ],\n                       [\n                           \"SourceEnvironmentId\",\n                           \"The unique id of the environment that you want to use as the source for the database refresh\\nThe Id can be located inside the LCS portal\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"TargetEnvironmentId\",\n                           \"The unique id of the environment that you want to use as the target for the database refresh\\nThe Id can be located inside the LCS portal\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"SkipInitialStatusFetch\",\n                           \"Instruct the cmdlet to skip the first fetch of the database refresh status\\nUseful when you have a large script that handles this status validation and you don\\u0027t want to spend time with this cmdlet\\nDefault output from this cmdlet is 2 (two) different objects. The first object is the response object for starting the refresh operation. The second object is the response object from fetching the \\r\\nstatus of the refresh operation.\\nSetting this parameter (activate it), will affect the number of output objects. If you skip, only the first response object outputted.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"FailOnErrorMessage\",\n                           \"Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\\r\\nThis allows you to implement custom retry / error handling logic\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"RetryTimeout\",\n                           \"The retry timeout, before the cmdlet should quit retrying based on the 429 status code\\nNeeds to be provided in the timspan notation:\\r\\n\\\"hh:mm:ss\\\"\\nhh is the number of hours, numerical notation only\\r\\nmm is the number of minutes\\r\\nss is the numbers of seconds\\nEach section of the timeout has to valid, e.g.\\r\\nhh can maximum be 23\\r\\nmm can maximum be 59\\r\\nss can maximum be 59\\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"00:00:00\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Start a database refresh between 2 environments\",\n        \"Name\":  \"Invoke-D365LcsDatabaseRefresh\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsDatabaseRefresh -ProjectId 123456789 -SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -TargetEnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -BearerToken \\r\\n\\\"JldjfafLJdfjlfsalfd...\\\" -LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\"\\nThis will start the database refresh between the Source and Target environments.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe source environment is identified by the SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which can be obtained in the LCS portal.\\r\\nThe target environment is identified by the TargetEnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\r\\nThe request will authenticate with the BearerToken \\\"JldjfafLJdfjlfsalfd...\\\".\\r\\nThe http request will be going to the LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\" (NON-EUROPE).\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsDatabaseRefresh -SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -TargetEnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\"\\nThis will start the database refresh between the Source and Target environments.\\r\\nThe source environment is identified by the SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which can be obtained in the LCS portal.\\r\\nThe target environment is identified by the TargetEnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003e$databaseRefresh = Invoke-D365LcsDatabaseRefresh -SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -TargetEnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -SkipInitialStatusFetch\\nPS C:\\\\\\u003e $databaseRefresh | Get-D365LcsDatabaseOperationStatus -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e9\\\" -SleepInSeconds 60\\nThis will start the database refresh between the Source and Target environments.\\r\\nThe source environment is identified by the SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which can be obtained in the LCS portal.\\r\\nThe target environment is identified by the TargetEnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\r\\nIt will skip the first database refesh status fetch and only output the details from starting the refresh.\\nThe output from Invoke-D365LcsDatabaseRefresh is stored in the $databaseRefresh. This will enable you to pass the $databaseRefresh variable to other cmdlets which should make things easier for you.\\nWill pipe the $databaseRefresh variable to the Get-D365LcsDatabaseOperationStatus cmdlet and get the status from the database refresh job.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsDatabaseRefresh -SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -TargetEnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -SkipInitialStatusFetch\\nThis will start the database refresh between the Source and Target environments.\\r\\nThe source environment is identified by the SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which can be obtained in the LCS portal.\\r\\nThe target environment is identified by the TargetEnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\r\\nIt will skip the first database refesh status fetch and only output the details from starting the refresh.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsDatabaseRefresh -SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -TargetEnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -RetryTimeout \\\"00:01:00\\\"\\nThis will start the database refresh between the Source and Target environments, and allow for the cmdlet to retry for no more than 1 minute.\\r\\nThe source environment is identified by the SourceEnvironmentId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which can be obtained in the LCS portal.\\r\\nThe target environment is identified by the TargetEnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\",\n        \"Syntax\":  \"Invoke-D365LcsDatabaseRefresh [[-ProjectId] \\u003cInt32\\u003e] [[-BearerToken] \\u003cString\\u003e] [-SourceEnvironmentId] \\u003cString\\u003e [-TargetEnvironmentId] \\u003cString\\u003e [[-LcsApiUri] \\u003cString\\u003e] [-SkipInitialStatusFetch] [-FailOnErrorMessage] [[-RetryTimeout] \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365LcsDeployment\",\n        \"Description\":  \"Deploy a deployable package from the Asset Library from a LCS project using the API provided by Microsoft\",\n        \"Tags\":  [\n                     \"Environment\",\n                     \"Url\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"LCS\",\n                     \"Upload\",\n                     \"Api\",\n                     \"AAD\",\n                     \"Token\",\n                     \"Deployment\",\n                     \"Deploy\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiProjectId\"\n                       ],\n                       [\n                           \"AssetId\",\n                           \"The unique id of the asset / file that you are trying to deploy from LCS\",\n                           \"\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"EnvironmentId\",\n                           \"The unique id of the environment that you want to work against\\nThe Id can be located inside the LCS portal\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"UpdateName\",\n                           \"Name of the update when you are working against Self-Service environments\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"Token\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiBearerToken\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"FailOnErrorMessage\",\n                           \"Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\\r\\nThis allows you to implement custom retry / error handling logic\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"RetryTimeout\",\n                           \"The retry timeout, before the cmdlet should quit retrying based on the 429 status code\\nNeeds to be provided in the timspan notation:\\r\\n\\\"hh:mm:ss\\\"\\nhh is the number of hours, numerical notation only\\r\\nmm is the number of minutes\\r\\nss is the numbers of seconds\\nEach section of the timeout has to valid, e.g.\\r\\nhh can maximum be 23\\r\\nmm can maximum be 59\\r\\nss can maximum be 59\\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"00:00:00\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Start the deployment of a deployable package\",\n        \"Name\":  \"Invoke-D365LcsDeployment\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsDeployment -ProjectId 123456789 -AssetId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -BearerToken \\\"Bearer JldjfafLJdfjlfsalfd...\\\" \\r\\n-LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\"\\nThis will start the deployment of the file located in the Asset Library.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe file is identified by the AssetId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which is obtained either by earlier upload or simply looking in the LCS portal.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\r\\nThe request will authenticate with the BearerToken \\\"Bearer JldjfafLJdfjlfsalfd...\\\".\\r\\nThe http request will be going to the LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\" (NON-EUROPE).\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsDeployment -AssetId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\"\\nThis will start the deployment of the file located in the Asset Library.\\r\\nThe file is identified by the AssetId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which is obtained either by earlier upload or simply looking in the LCS portal.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsDeployment -AssetId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -UpdateName \\\"Release_XYZ\\\"\\nThis will start the deployment of the file located in the Asset Library against a Self-Service environment.\\r\\nThe file is identified by the AssetId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which is obtained either by earlier upload or simply looking in the LCS portal.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\r\\nThe deployment is name \\\"Release_XYZ\\\" by setting the UpdateName parameter, which is mandatory when working against Self-Service environments.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsDeployment -AssetId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\" -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -RetryTimeout \\\"00:01:00\\\"\\nThis will start the deployment of the file located in the Asset Library, and allow for the cmdlet to retry for no more than 1 minute.\\r\\nThe file is identified by the AssetId \\\"958ae597-f089-4811-abbd-c1190917eaae\\\", which is obtained either by earlier upload or simply looking in the LCS portal.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\",\n        \"Syntax\":  \"Invoke-D365LcsDeployment [-ProjectId \\u003cInt32\\u003e] -AssetId \\u003cString\\u003e -EnvironmentId \\u003cString\\u003e [-BearerToken \\u003cString\\u003e] [-LcsApiUri \\u003cString\\u003e] [-FailOnErrorMessage] [-RetryTimeout \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\\nInvoke-D365LcsDeployment [-ProjectId \\u003cInt32\\u003e] -AssetId \\u003cString\\u003e -EnvironmentId \\u003cString\\u003e -UpdateName \\u003cString\\u003e [-BearerToken \\u003cString\\u003e] [-LcsApiUri \\u003cString\\u003e] [-FailOnErrorMessage] [-RetryTimeout \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365LcsEnvironmentStart\",\n        \"Description\":  \"Start a specified IAAS environment that is Customer Managed through the LCS API.\",\n        \"Tags\":  [\n                     \"Environment\",\n                     \"Start\",\n                     \"StartStop\",\n                     \"Stop\",\n                     \"LCS\",\n                     \"Api\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiProjectId\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"Token\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiBearerToken\"\n                       ],\n                       [\n                           \"EnvironmentId\",\n                           \"The unique id of the environment that you want to take action upon\\nThe Id can be located inside the LCS portal\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"FailOnErrorMessage\",\n                           \"Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\\r\\nThis allows you to implement custom retry / error handling logic\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"RetryTimeout\",\n                           \"The retry timeout, before the cmdlet should quit retrying based on the 429 status code\\nNeeds to be provided in the timspan notation:\\r\\n\\\"hh:mm:ss\\\"\\nhh is the number of hours, numerical notation only\\r\\nmm is the number of minutes\\r\\nss is the numbers of seconds\\nEach section of the timeout has to valid, e.g.\\r\\nhh can maximum be 23\\r\\nmm can maximum be 59\\r\\nss can maximum be 59\\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"00:00:00\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi), Billy Richardson (@richardsondev)\",\n        \"Synopsis\":  \"Start a specified environment through LCS.\",\n        \"Name\":  \"Invoke-D365LcsEnvironmentStart\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsEnvironmentStart -ProjectId 123456789 -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -BearerToken \\\"JldjfafLJdfjlfsalfd...\\\" -LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\"\\nThis will trigger the environment start operation upon the given environment through the LCS API.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\r\\nThe request will authenticate with the BearerToken \\\"JldjfafLJdfjlfsalfd...\\\".\\r\\nThe http request will be going to the LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\"\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsEnvironmentStart -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\"\\nThis will trigger the environment start operation upon the given environment through the LCS API.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsEnvironmentStart -ProjectId 123456789 -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -RetryTimeout \\\"00:01:00\\\"\\nThis will trigger the environment start operation upon the given environment through the LCS API, and allow for the cmdlet to retry for no more than 1 minute.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\",\n        \"Syntax\":  \"Invoke-D365LcsEnvironmentStart [[-ProjectId] \\u003cInt32\\u003e] [[-BearerToken] \\u003cString\\u003e] [-EnvironmentId] \\u003cString\\u003e [[-LcsApiUri] \\u003cString\\u003e] [-FailOnErrorMessage] [[-RetryTimeout] \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365LcsEnvironmentStop\",\n        \"Description\":  \"Stop a specified IAAS environment that is Customer Managed through the LCS API.\",\n        \"Tags\":  [\n                     \"Environment\",\n                     \"Stop\",\n                     \"StartStop\",\n                     \"Start\",\n                     \"LCS\",\n                     \"Api\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiProjectId\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"Token\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiBearerToken\"\n                       ],\n                       [\n                           \"EnvironmentId\",\n                           \"The unique id of the environment that you want to take action upon\\nThe Id can be located inside the LCS portal\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"FailOnErrorMessage\",\n                           \"Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\\r\\nThis allows you to implement custom retry / error handling logic\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"RetryTimeout\",\n                           \"The retry timeout, before the cmdlet should quit retrying based on the 429 status code\\nNeeds to be provided in the timspan notation:\\r\\n\\\"hh:mm:ss\\\"\\nhh is the number of hours, numerical notation only\\r\\nmm is the number of minutes\\r\\nss is the numbers of seconds\\nEach section of the timeout has to valid, e.g.\\r\\nhh can maximum be 23\\r\\nmm can maximum be 59\\r\\nss can maximum be 59\\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"00:00:00\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi), Billy Richardson (@richardsondev)\",\n        \"Synopsis\":  \"Stop a specified environment through LCS.\",\n        \"Name\":  \"Invoke-D365LcsEnvironmentStop\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsEnvironmentStop -ProjectId 123456789 -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -BearerToken \\\"JldjfafLJdfjlfsalfd...\\\" -LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\"\\nThis will trigger the environment stop operation upon the given environment through the LCS API.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\r\\nThe request will authenticate with the BearerToken \\\"JldjfafLJdfjlfsalfd...\\\".\\r\\nThe http request will be going to the LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\"\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsEnvironmentStop -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\"\\nThis will trigger the environment stop operation upon the given environment through the LCS API.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsEnvironmentStop -ProjectId 123456789 -EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\" -RetryTimeout \\\"00:01:00\\\"\\nThis will trigger the environment stop operation upon the given environment through the LCS API, and allow for the cmdlet to retry for no more than 1 minute.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe environment is identified by the EnvironmentId \\\"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\\\", which can be obtained in the LCS portal.\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\",\n        \"Syntax\":  \"Invoke-D365LcsEnvironmentStop [[-ProjectId] \\u003cInt32\\u003e] [[-BearerToken] \\u003cString\\u003e] [-EnvironmentId] \\u003cString\\u003e [[-LcsApiUri] \\u003cString\\u003e] [-FailOnErrorMessage] [[-RetryTimeout] \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365LcsUpload\",\n        \"Description\":  \"Upload a file to a LCS project using the API provided by Microsoft\",\n        \"Tags\":  [\n                     \"Environment\",\n                     \"Url\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"LCS\",\n                     \"Upload\",\n                     \"Api\",\n                     \"AAD\",\n                     \"Token\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiProjectId\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"Token\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiBearerToken\"\n                       ],\n                       [\n                           \"FilePath\",\n                           \"Path to the file that you want to upload to the Asset Library on LCS\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"FileType\",\n                           \"Type of file you want to upload\\nValid options:\\r\\n\\\"Model\\\"\\r\\n\\\"Process Data Package\\\"\\r\\n\\\"Software Deployable Package\\\"\\r\\n\\\"GER Configuration\\\"\\r\\n\\\"Data Package\\\"\\r\\n\\\"PowerBI Report Model\\\"\\r\\n\\\"E-Commerce Package\\\"\\r\\n\\\"NuGet Package\\\"\\r\\n\\\"Retail Self-Service Package\\\"\\r\\n\\\"Commerce Cloud Scale Unit Extension\\\"\\nDefault value is \\\"Software Deployable Package\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"SoftwareDeployablePackage\"\n                       ],\n                       [\n                           \"Name\",\n                           \"Name to be assigned / shown on LCS\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Filename\",\n                           \"Filename to be assigned / shown on LCS\\nOften will it require an extension for it to be accepted\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"FileDescription\",\n                           \"Description to be assigned / shown on LCS\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"FailOnErrorMessage\",\n                           \"Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\\r\\nThis allows you to implement custom retry / error handling logic\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"RetryTimeout\",\n                           \"The retry timeout, before the cmdlet should quit retrying based on the 429 status code\\nNeeds to be provided in the timspan notation:\\r\\n\\\"hh:mm:ss\\\"\\nhh is the number of hours, numerical notation only\\r\\nmm is the number of minutes\\r\\nss is the numbers of seconds\\nEach section of the timeout has to valid, e.g.\\r\\nhh can maximum be 23\\r\\nmm can maximum be 59\\r\\nss can maximum be 59\\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"00:00:00\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Upload a file to a LCS project\",\n        \"Name\":  \"Invoke-D365LcsUpload\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsUpload -ProjectId 123456789 -BearerToken \\\"Bearer JldjfafLJdfjlfsalfd...\\\" -FilePath \\\"C:\\\\temp\\\\d365fo.tools\\\\Release-2019-05-05.zip\\\" -FileType \\\"SoftwareDeployablePackage\\\" -Name \\r\\n\\\"Release-2019-05-05\\\" -Filename \\\"Release-2019-05-05.zip\\\" -FileDescription \\\"Build based on sprint: SuperSprint-1\\\" -LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\"\\nThis will start the upload of a file to the Asset Library.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe file that will be uploaded is based on the FilePath \\\"C:\\\\temp\\\\d365fo.tools\\\\Release-2019-05-05.zip\\\".\\r\\nThe file type \\\"Software Deployable Package\\\" determines where inside the Asset Library the file will end up.\\r\\nThe name inside the Asset Library is based on the Name \\\"Release-2019-05-05\\\".\\r\\nThe file name inside the Asset Library is based on the FileName \\\"Release-2019-05-05.zip\\\".\\r\\nThe description inside the Asset Library is based on the FileDescription \\\"Build based on sprint: SuperSprint-1\\\".\\r\\nThe request will authenticate with the BearerToken \\\"Bearer JldjfafLJdfjlfsalfd...\\\".\\r\\nThe http request will be going to the LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\" (NON-EUROPE).\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsUpload -FilePath \\\"C:\\\\temp\\\\d365fo.tools\\\\Release-2019-05-05.zip\\\" -FileType \\\"SoftwareDeployablePackage\\\" -FileName \\\"Release-2019-05-05.zip\\\"\\nThis will start the upload of a file to the Asset Library.\\r\\nThe file that will be uploaded is based on the FilePath \\\"C:\\\\temp\\\\d365fo.tools\\\\Release-2019-05-05.zip\\\".\\r\\nThe file type \\\"Software Deployable Package\\\" determines where inside the Asset Library the file will end up.\\r\\nThe file name inside the Asset Library is based on the FileName \\\"Release-2019-05-05.zip\\\".\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsUpload -FilePath \\\"C:\\\\temp\\\\d365fo.tools\\\\Release-2019-05-05.zip\\\"\\nThis will start the upload of a file to the Asset Library.\\r\\nThe file that will be uploaded is based on the FilePath \\\"C:\\\\temp\\\\d365fo.tools\\\\Release-2019-05-05.zip\\\".\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eInvoke-D365LcsUpload -FilePath \\\"C:\\\\temp\\\\d365fo.tools\\\\Release-2019-05-05.zip\\\" -RetryTimeout \\\"00:01:00\\\"\\nThis will start the upload of a file to the Asset Library through the LCS API, and allow for the cmdlet to retry for no more than 1 minute.\\r\\nThe file that will be uploaded is based on the FilePath \\\"C:\\\\temp\\\\d365fo.tools\\\\Release-2019-05-05.zip\\\".\\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\\nThe default values can be configured using Set-D365LcsApiConfig.\",\n        \"Syntax\":  \"Invoke-D365LcsUpload [[-ProjectId] \\u003cInt32\\u003e] [[-BearerToken] \\u003cString\\u003e] [-FilePath] \\u003cString\\u003e [[-FileType] {Model | ProcessDataPackage | SoftwareDeployablePackage | GERConfiguration | DataPackage | PowerBIReportModel | ECommercePackage | NuGetPackage | RetailSelfServicePackage | CommerceCloudScaleUnitExtension}] [[-Name] \\u003cString\\u003e] [[-Filename] \\u003cString\\u003e] [[-FileDescription] \\u003cString\\u003e] [[-LcsApiUri] \\u003cString\\u003e] [-FailOnErrorMessage] [[-RetryTimeout] \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365ModuleCompile\",\n        \"Description\":  \"Compile a package / module / model using the builtin \\\"xppc.exe\\\" executable to compile source code\",\n        \"Tags\":  [\n                     \"Compile\",\n                     \"Model\",\n                     \"Servicing\",\n                     \"X++\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Module\",\n                           \"The package to compile\",\n                           \"ModuleName\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"OutputDir\",\n                           \"The path to the folder to save generated artifacts\",\n                           \"Output\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"Path where you want to store the log outputs generated from the compiler\\nAlso used as the path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\ModuleCompile\\\")\"\n                       ],\n                       [\n                           \"MetaDataDir\",\n                           \"The path to the meta data directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"ReferenceDir\",\n                           \"The full path of a folder containing all assemblies referenced from X++ code\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:BinDirTools\"\n                       ],\n                       [\n                           \"XRefSqlServer\",\n                           \"The name of the SQL server where the cross references database is located; the default is \\\"$env:COMPUTERNAME\\\"\\r\\nThis parameter is only used for XRefGenerationOnly\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$env:COMPUTERNAME\"\n                       ],\n                       [\n                           \"XRefDbName\",\n                           \"The name of the cross references database; the default is \\\"DYNAMICSXREFDB\\\"\\r\\nThis parameter is only used for XRefGenerationOnly\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"DYNAMICSXREFDB\"\n                       ],\n                       [\n                           \"XRefGeneration\",\n                           \"Instruct the cmdlet to enable the generation of XRef metadata while running the compile\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"XRefGenerationOnly\",\n                           \"Instruct the cmdlet to only generate XRef metadata while running the compile and not update the assemblies and PDB files\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Ievgen Miroshnikov (@IevgenMir)\",\n        \"Synopsis\":  \"Compile a package / module / model\",\n        \"Name\":  \"Invoke-D365ModuleCompile\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365ModuleCompile -Module MyModel\\nThis will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package.\\r\\nThe default output from the compile will be silenced.\\nIf an error should occur, both the standard output and error output will be written to the console / host.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365ModuleCompile -Module MyModel -ShowOriginalProgress\\nThis will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package.\\r\\nThe output from the compile will be written to the console / host.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eInvoke-D365ModuleCompile -Module MyModel -XRefGeneration\\nThis will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package.\\r\\nThe default output from the compile will be silenced.\\r\\nThe compiler will generate XRef metadata while compiling.\\nIf an error should occur, both the standard output and error output will be written to the console / host.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eInvoke-D365ModuleCompile -Module MyModel -XRefGenerationOnly\\nThis will use the default paths and start the xppc.exe with the needed parameters to only generate cross references for the MyModel package.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eGet-D365Module -ExcludeBinaryModules -InDependencyOrder | Invoke-D365ModuleCompile -XRefGenerationOnly -ShowOriginalProgress\\nThis will update all cross references, keeping the assemblies and PDB files unmodified.\\r\\nThe output from the compile will be written to the console / host.\",\n        \"Syntax\":  \"Invoke-D365ModuleCompile [-Module] \\u003cString\\u003e [[-OutputDir] \\u003cString\\u003e] [[-LogPath] \\u003cString\\u003e] [[-MetaDataDir] \\u003cString\\u003e] [[-ReferenceDir] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [[-XRefSqlServer] \\u003cString\\u003e] [[-XRefDbName] \\u003cString\\u003e] [-XRefGeneration] [-XRefGenerationOnly] [-ShowOriginalProgress] [-OutputCommandOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365ModuleFullCompile\",\n        \"Description\":  \"Compile a package using the builtin \\\"xppc.exe\\\" executable to compile source code, \\\"labelc.exe\\\" to compile label files and \\\"reportsc.exe\\\" to compile reports\",\n        \"Tags\":  [\n                     \"Compile\",\n                     \"Model\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Module\",\n                           \"The package to compile\",\n                           \"ModuleName\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"OutputDir\",\n                           \"The path to the folder to save assemblies\",\n                           \"Output\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"Path where you want to store the log outputs generated from the compiler\\nAlso used as the path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\ModuleCompile\\\")\"\n                       ],\n                       [\n                           \"MetaDataDir\",\n                           \"The path to the meta data directory for the environment\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"ReferenceDir\",\n                           \"The full path of a folder containing all assemblies referenced from X++ code\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:BinDirTools\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Ievgen Miroshnikov (@IevgenMir)\",\n        \"Synopsis\":  \"Compile a package\",\n        \"Name\":  \"Invoke-D365ModuleFullCompile\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365ModuleFullCompile -Module MyModel\\nThis will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package.\\r\\nThe default output from all the different steps will be silenced.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365ModuleFullCompile -Module MyModel -ShowOriginalProgress\\nThis will use the default paths and start the xppc.exe with the needed parameters to copmile MyModel package.\\r\\nThe default output from the different steps will be written to the console / host.\",\n        \"Syntax\":  \"Invoke-D365ModuleFullCompile [-Module] \\u003cString\\u003e [[-OutputDir] \\u003cString\\u003e] [[-LogPath] \\u003cString\\u003e] [[-MetaDataDir] \\u003cString\\u003e] [[-ReferenceDir] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365ModuleLabelGeneration\",\n        \"Description\":  \"Generate labels for a package / module / model using the builtin \\\"labelc.exe\\\"\",\n        \"Tags\":  [\n                     \"Compile\",\n                     \"Model\",\n                     \"Servicing\",\n                     \"Label\",\n                     \"Labels\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Module\",\n                           \"Name of the package that you want to work against\",\n                           \"ModuleName\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"OutputDir\",\n                           \"The path to the folder to save generated artifacts\",\n                           \"Output\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"Path where you want to store the log outputs generated from the compiler\\nAlso used as the path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\ModuleCompile\\\")\"\n                       ],\n                       [\n                           \"MetaDataDir\",\n                           \"The path to the meta data directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"ReferenceDir\",\n                           \"The full path of a folder containing all assemblies referenced from X++ code\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:BinDirTools\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Ievgen Miroshnikov (@IevgenMir)\",\n        \"Synopsis\":  \"Generate labels for a package / module / model\",\n        \"Name\":  \"Invoke-D365ModuleLabelGeneration\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365ModuleLabelGeneration -Module MyModel\\nThis will use the default paths and start the labelc.exe with the needed parameters to labels from the MyModel package.\\r\\nThe default output from the generation process will be silenced.\\nIf an error should occur, both the standard output and error output will be written to the console / host.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365ModuleLabelGeneration -Module MyModel -ShowOriginalProgress\\nThis will use the default paths and start the labelc.exe with the needed parameters to labels from the MyModel package.\\r\\nThe output from the compile will be written to the console / host.\",\n        \"Syntax\":  \"Invoke-D365ModuleLabelGeneration [-Module] \\u003cString\\u003e [[-OutputDir] \\u003cString\\u003e] [[-LogPath] \\u003cString\\u003e] [[-MetaDataDir] \\u003cString\\u003e] [[-ReferenceDir] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365ModuleReportsCompile\",\n        \"Description\":  \"Generate reports for a package / module / model using the builtin \\\"ReportsC.exe\\\"\",\n        \"Tags\":  [\n                     \"Compile\",\n                     \"Model\",\n                     \"Servicing\",\n                     \"Report\",\n                     \"Reports\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Module\",\n                           \"Name of the package that you want to work against\",\n                           \"ModuleName\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"OutputDir\",\n                           \"The path to the folder to save generated artifacts\",\n                           \"Output\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"Path where you want to store the log outputs generated from the compiler\\nAlso used as the path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\ModuleCompile\\\")\"\n                       ],\n                       [\n                           \"MetaDataDir\",\n                           \"The path to the meta data directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"ReferenceDir\",\n                           \"The full path of a folder containing all assemblies referenced from X++ code\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:BinDirTools\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Ievgen Miroshnikov (@IevgenMir)\",\n        \"Synopsis\":  \"Generate reports for a package / module / model\",\n        \"Name\":  \"Invoke-D365ModuleReportsCompile\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365ModuleReportsCompile -Module MyModel\\nThis will use the default paths and start the ReportsC.exe with the needed parameters to compile the reports from the MyModel package.\\r\\nThe default output from the reports compile will be silenced.\\nIf an error should occur, both the standard output and error output will be written to the console / host.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365ModuleReportsCompile -Module MyModel -ShowOriginalProgress\\nThis will use the default paths and start the ReportsC.exe with the needed parameters to compile the reports from the MyModel package.\\r\\nThe output from the compile will be written to the console / host.\",\n        \"Syntax\":  \"Invoke-D365ModuleReportsCompile [-Module] \\u003cString\\u003e [[-OutputDir] \\u003cString\\u003e] [[-LogPath] \\u003cString\\u003e] [[-MetaDataDir] \\u003cString\\u003e] [[-ReferenceDir] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365ProcessModule\",\n        \"Description\":  \"Process a specific or multiple modules by invoking the following functions (based on flags)\\n- Invoke-D365ModuleFullCompile function\\n- Publish-D365SsrsReport to deploy the reports of a module\\n- Invoke-D365DBSyncPartial to sync the table and extension elements for module\",\n        \"Tags\":  [\n                     \"Compile\",\n                     \"Model\",\n                     \"Servicing\",\n                     \"Database\",\n                     \"Synchronization\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Module\",\n                           \"Name of the module that you want to process\\nAccepts wildcards for searching. E.g. -Module \\\"Application*Adaptor\\\"\\nDefault value is \\\"*\\\" which will search for all modules\",\n                           \"ModuleName\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ExecuteCompile\",\n                           \"Switch/flag to determine if the compile function should be executed for requested modules\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"ExecuteSync\",\n                           \"Switch/flag to determine if the databasesync function should be executed for requested modules\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"ExecuteDeployReports\",\n                           \"Switch/flag to determine if the deploy reports function should be executed for requested modules\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputDir\",\n                           \"The path to the folder to save assemblies\",\n                           \"Output\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"Path where you want to store the log outputs generated from the compiler\\nAlso used as the path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\ModuleCompile\\\")\"\n                       ],\n                       [\n                           \"MetaDataDir\",\n                           \"The path to the meta data directory for the environment\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"ReferenceDir\",\n                           \"The full path of a folder containing all assemblies referenced from X++ code\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:MetaDataDir\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:BinDirTools\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Jasper Callens - Cegeka\",\n        \"Synopsis\":  \"Process a specific or multiple modules (compile, deploy reports and sync)\",\n        \"Name\":  \"Invoke-D365ProcessModule\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365ProcessModule -Module \\\"Application*Adaptor\\\" -ExecuteCompile\\nRetrieve the list of installed packages / modules where the name fits the search \\\"Application*Adaptor\\\".\\nFor every value of the list perform the following:\\r\\n* Invoke-D365ModuleFullCompile with the needed parameters to compile current module value package.\\nThe default output from all the different steps will be silenced.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365ProcessModule -Module \\\"Application*Adaptor\\\" -ExecuteSync\\nRetrieve the list of installed packages / modules where the name fits the search \\\"Application*Adaptor\\\".\\nFor every value of the list perform the following:\\r\\n* Invoke-D365DBSyncPartial with the needed parameters to sync current module value table and extension elements.\\nThe default output from all the different steps will be silenced.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eInvoke-D365ProcessModule -Module \\\"Application*Adaptor\\\" -ExecuteDeployReports\\nRetrieve the list of installed packages / modules where the name fits the search \\\"Application*Adaptor\\\".\\nFor every value of the list perform the following:\\r\\n* Publish-D365SsrsReport with the required parameters to deploy all reports of current module\\nThe default output from all the different steps will be silenced.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eInvoke-D365ProcessModule -Module \\\"Application*Adaptor\\\" -ExecuteCompile -ExecuteSync -ExecuteDeployReports\\nRetrieve the list of installed packages / modules where the name fits the search \\\"Application*Adaptor\\\".\\nFor every value of the list perform the following:\\r\\n* Invoke-D365ModuleFullCompile with the needed parameters to compile current module package.\\r\\n* Invoke-D365DBSyncPartial with the needed parameters to sync current module table and extension elements.\\r\\n* Publish-D365SsrsReport with the required parameters to deploy all reports of current module\\nThe default output from all the different steps will be silenced.\",\n        \"Syntax\":  \"Invoke-D365ProcessModule [-Module] \\u003cString\\u003e [-ExecuteCompile] [-ExecuteSync] [-ExecuteDeployReports] [[-OutputDir] \\u003cString\\u003e] [[-LogPath] \\u003cString\\u003e] [[-MetaDataDir] \\u003cString\\u003e] [[-ReferenceDir] \\u003cString\\u003e] [[-BinDir] \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365ReArmWindows\",\n        \"Description\":  \"Function used for invoking the rearm functionality inside Windows\",\n        \"Params\":  [\n                       [\n                           \"Restart\",\n                           \"Instruct the cmdlet to restart the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Invokes the Rearm of Windows license\",\n        \"Name\":  \"Invoke-D365ReArmWindows\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365ReArmWindows\\nThis will re arm the Windows installation if there is any activation retries left\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365ReArmWindows -Restart\\nThis will re arm the Windows installation if there is any activation retries left and restart the computer.\",\n        \"Syntax\":  \"Invoke-D365ReArmWindows [[-Restart]] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365RunbookAnalyzer\",\n        \"Description\":  \"Get all the important details from a failed runbook\",\n        \"Tags\":  [\n                     \"Runbook\",\n                     \"Servicing\",\n                     \"Hotfix\",\n                     \"DeployablePackage\",\n                     \"Deployable Package\",\n                     \"InstallationRecordsDirectory\",\n                     \"Installation Records Directory\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the runbook file that you work against\",\n                           \"File\",\n                           true,\n                           \"true (ByValue, ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"FailedOnly\",\n                           \"Instruct the cmdlet to only output failed steps\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"FailedOnlyAsObjects\",\n                           \"Instruct the cmdlet to only output failed steps as objects\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Analyze the runbook\",\n        \"Name\":  \"Invoke-D365RunbookAnalyzer\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365RunbookAnalyzer -Path \\\"C:\\\\DynamicsAX\\\\InstallationRecords\\\\Runbooks\\\\Runbook.xml\\\"\\nThis will analyze the Runbook.xml and output all the details about failed steps, the connected error logs and all the unprocessed steps.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365Runbook -Latest | Invoke-D365RunbookAnalyzer\\nThis will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eGet-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnly\\nThis will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\\r\\nThe output from Invoke-D365RunbookAnalyzer will only contain failed steps.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnlyAsObjects\\nThis will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\\r\\nThe output from Invoke-D365RunbookAnalyzer will only contain failed steps.\\r\\nThe output will be formatted as PSCustomObjects, to be used as variables or piping.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eGet-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnlyAsObjects | Get-D365RunbookLogFile -Path \\\"C:\\\\Temp\\\\PU35\\\" -OpenInEditor\\nThis will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\\r\\nThe output from Invoke-D365RunbookAnalyzer will only contain failed steps.\\r\\nThe Get-D365RunbookLogFile will open all log files for the failed step.\\n-------------------------- EXAMPLE 6 --------------------------\\nPS C:\\\\\\u003eGet-D365Runbook -Latest | Invoke-D365RunbookAnalyzer | Out-File \\\"C:\\\\Temp\\\\d365fo.tools\\\\runbook-analyze-results.xml\\\"\\nThis will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\\r\\nThe output will be saved into the \\\"C:\\\\Temp\\\\d365fo.tools\\\\runbook-analyze-results.xml\\\" file.\\n-------------------------- EXAMPLE 7 --------------------------\\nPS C:\\\\\\u003eGet-D365Runbook -Latest | Backup-D365Runbook -Force | Invoke-D365RunbookAnalyzer\\nThis will get the latest runbook from the default location.\\r\\nThis will backup the file onto the default \\\"c:\\\\temp\\\\d365fo.tools\\\\runbookbackups\\\\\\\".\\r\\nThis will start the Runbook Analyzer on the backup file.\",\n        \"Syntax\":  \"Invoke-D365RunbookAnalyzer -Path \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\\nInvoke-D365RunbookAnalyzer -Path \\u003cString\\u003e [-FailedOnlyAsObjects] [\\u003cCommonParameters\\u003e]\\nInvoke-D365RunbookAnalyzer -Path \\u003cString\\u003e [-FailedOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365SCDPBundleInstall\",\n        \"Description\":  \"A cmdlet that wraps some of the cumbersome work of installing updates / hotfixes into a streamlined process\",\n        \"Tags\":  [\n                     \"Hotfix\",\n                     \"Hotfixes\",\n                     \"Updates\",\n                     \"Prepare\",\n                     \"VSTS\",\n                     \"axscdppkg\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"InstallOnly\",\n                           \"Instructs the cmdlet to only run the Install option and ignore any TFS / VSTS folders and source control in general\\nUse it when testing an update on a local development machine (VM) / onebox\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Command\",\n                           \"The command / job you want the cmdlet to execute\\nValid options are:\\r\\nPrepare\\r\\nInstall\\nDefault value is \\\"Prepare\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"Prepare\"\n                       ],\n                       [\n                           \"Path\",\n                           \"Path to the update package that you want to install into the environment\\nThe cmdlet only supports an already extracted \\\".axscdppkg\\\" file\",\n                           \"File,Hotfix\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"MetaDataDir\",\n                           \"The path to the meta data directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:MetaDataDir\\\"\"\n                       ],\n                       [\n                           \"TfsWorkspaceDir\",\n                           \"The path to the TFS Workspace directory that you want to work against\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:MetaDataDir\\\"\"\n                       ],\n                       [\n                           \"TfsUri\",\n                           \"The URI for the TFS Team Site / VSTS Portal that you want to work against\\nDefault URI is the one that is configured from inside Visual Studio\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:TfsUri\\\"\"\n                       ],\n                       [\n                           \"ShowModifiedFiles\",\n                           \"Switch to instruct the cmdlet to show all the modified files afterwards\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"ShowProgress\",\n                           \"Switch to instruct the cmdlet to output progress details while servicing the installation\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@splaxi)\",\n        \"Synopsis\":  \"Invoke the SCDPBundleInstall.exe file\",\n        \"Name\":  \"Invoke-D365SCDPBundleInstall\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365SCDPBundleInstall -Path \\\"c:\\\\temp\\\\HotfixPackageBundle.axscdppkg\\\" -InstallOnly\\nThis will install the \\\"HotfixPackageBundle.axscdppkg\\\" into the default PackagesLocalDirectory location on the machine.\",\n        \"Syntax\":  \"Invoke-D365SCDPBundleInstall [-InstallOnly] [-Path] \\u003cString\\u003e [[-MetaDataDir] \\u003cString\\u003e] [[-ShowModifiedFiles]] [[-ShowProgress]] [\\u003cCommonParameters\\u003e]\\nInvoke-D365SCDPBundleInstall [[-Command] \\u003cString\\u003e] [-Path] \\u003cString\\u003e [[-MetaDataDir] \\u003cString\\u003e] [[-TfsWorkspaceDir] \\u003cString\\u003e] [[-TfsUri] \\u003cString\\u003e] [[-ShowModifiedFiles]] [[-ShowProgress]] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365SDPInstall\",\n        \"Description\":  \"A cmdlet that wraps some of the cumbersome work into a streamlined process.\\nThe process for a legacy (i.e. non unified) environment are detailed in the Microsoft documentation here:\\nhttps://docs.microsoft.com/en-us/dynamics365/unified-operations/dev-itpro/deployment/install-deployable-package\",\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the update package that you want to install into the environment\\nThe cmdlet supports a path to a zip-file or directory with the unpacked contents.\",\n                           \"File,Hotfix\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"MetaDataDir\",\n                           \"The path to the meta data directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:MetaDataDir\\\"\"\n                       ],\n                       [\n                           \"QuickInstallAll\",\n                           \"Use this switch to let the runbook reside in memory. You will not get a runbook on disc which you can examine for steps\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"DevInstall\",\n                           \"Use this when running on developer box without administrator privileges (Run As Administrator)\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Command\",\n                           \"The command you want the cmdlet to execute when it runs the AXUpdateInstaller.exe\\nValid options are:\\r\\nSetTopology\\r\\nGenerate\\r\\nImport\\r\\nExecute\\r\\nRunAll\\r\\nReRunStep\\r\\nSetStepComplete\\r\\nExport\\r\\nVersionCheck\\nThe default value is \\\"SetTopology\\\"\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"SetTopology\"\n                       ],\n                       [\n                           \"Step\",\n                           \"The step number that you want to work against\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"0\"\n                       ],\n                       [\n                           \"RunbookId\",\n                           \"The runbook id of the runbook that you want to work against\\nDefault value is \\\"Runbook\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"Runbook\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"The path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\SdpInstall\\\")\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"TopologyFile\",\n                           \"Provide a custom topology file to use. By default, the cmdlet will use the DefaultTopologyData.xml file in the package directory.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"DefaultTopologyData.xml\"\n                       ],\n                       [\n                           \"UseExistingTopologyFile\",\n                           \"Use this switch to indicate that the topology file is already updated and should not be updated again.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"UnifiedDevelopmentEnvironment\",\n                           \"Use this switch to install the package in a Unified Development Environment (UDE).\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"IncludeFallbackRetailServiceModels\",\n                           \"Include fallback retail service models in the topology file\\nThis parameter is to support backward compatibility in this scenario:\\r\\nInstalling the first update on a local VHD where the information about the installed service\\r\\nmodels may not be available and where the retail components are installed.\\r\\nMore information about this can be found at https://github.com/d365collaborative/d365fo.tools/issues/878\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Instruct the cmdlet to overwrite the \\\"extracted\\\" folder if it exists\\nUsed when the input is a zip file, that will auto extract to a folder named like the zip file.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"ForceFallbackServiceModels\",\n                           \"Force the use of the fallback list of known service model names\\nThis parameter supports update scenarios primarily on local VHDs where the information about\\r\\nthe installed service models may be incomplete. In such a case, the user receives a warning\\r\\nand a suggestion to use this parameter.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Tommy Skaue (@skaue)\",\n        \"Synopsis\":  \"Install a Software Deployable Package (SDP)\",\n        \"Name\":  \"Invoke-D365SDPInstall\",\n        \"Links\":  null,\n        \"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.\\n-------------------------- EXAMPLE 9 --------------------------\\nPS C:\\\\\\u003eInvoke-D365SDPInstall -Path \\\"c:\\\\temp\\\\\\\" -MetaDataDir \\\"c:\\\\MyRepository\\\\Metadata\\\" -UnifiedDevelopmentEnvironment\\nInstall the modules contained in the c:\\\\temp\\\\ directory into the c:\\\\MyRepository\\\\Metadata directory.\\n-------------------------- EXAMPLE 10 --------------------------\\nPS C:\\\\\\u003eInvoke-D365SDPInstall -Path \\\"c:\\\\temp\\\\\\\" -Command RunAll -IncludeFallbackRetailServiceModels\\nCreate Topology XML from current environment. If the current environment does not have the information about the installed service models, a fallback list of known service model names will be used.\\r\\nThis fallback list includes the retail service models.\\r\\nUsing default runbook id \\u0027Runbook\\u0027 and run all the operations from generate, to import to execute.\\n-------------------------- EXAMPLE 11 --------------------------\\nPS C:\\\\\\u003eInvoke-D365SDPInstall -Path \\\"c:\\\\temp\\\\\\\" -Command RunAll -ForceFallbackServiceModels\\nCreate Topology XML from current environment. If the current environment does have no or only partial information about the installed service models, a fallback list of known service model names will \\r\\nbe used.\\r\\nThis fallback list does not include the retail service models.\\r\\nUsing default runbook id \\u0027Runbook\\u0027 and run all the operations from generate, to import to execute.\",\n        \"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] [-IncludeFallbackRetailServiceModels] [-Force] [-ForceFallbackServiceModels] [\\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] [-IncludeFallbackRetailServiceModels] [-Force] [-ForceFallbackServiceModels] [\\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] [-IncludeFallbackRetailServiceModels] [-Force] [-ForceFallbackServiceModels] [\\u003cCommonParameters\\u003e]\\nInvoke-D365SDPInstall [-Path] \\u003cString\\u003e [[-MetaDataDir] \\u003cString\\u003e] [[-Step] \\u003cInt32\\u003e] [[-RunbookId] \\u003cString\\u003e] [-LogPath \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [-TopologyFile \\u003cString\\u003e] [-UseExistingTopologyFile] [-UnifiedDevelopmentEnvironment] [-IncludeFallbackRetailServiceModels] [-Force] [-ForceFallbackServiceModels] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365SDPInstallUDE\",\n        \"Description\":  \"A cmdlet that wraps some of the cumbersome work into a streamlined process.\\nIt first checks if the package is a zip file and extracts it if necessary.\\nThen it checks if the package contains the necessary files and modules.\\nFinally, it extracts the module zip files into the metadata directory.\",\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the package that you want to install into the environment\\nThe cmdlet supports a path to a zip-file or directory with the unpacked contents.\",\n                           \"File,Hotfix\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"MetaDataDir\",\n                           \"The path to the meta data directory for the environment\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"The path where the log file(s) will be saved\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\SdpInstall\\\")\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Instruct the cmdlet to overwrite the \\\"extracted\\\" folder if it exists\\nUsed when the input is a zip file, that will auto extract to a folder named like the zip file.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Florian Hopfner (@FH-Inway)\",\n        \"Synopsis\":  \"Install a Software Deployable Package (SDP) in a unified development environment\",\n        \"Name\":  \"Invoke-D365SDPInstallUDE\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365SDPInstallUDE -Path \\\"c:\\\\temp\\\\package.zip\\\" -MetaDataDir \\\"c:\\\\MyRepository\\\\Metadata\\\"\\nThis will install the modules contained in the c:\\\\temp\\\\package.zip file into the c:\\\\MyRepository\\\\Metadata directory.\",\n        \"Syntax\":  \"Invoke-D365SDPInstallUDE [-Path] \\u003cString\\u003e [-MetaDataDir] \\u003cString\\u003e [-LogPath \\u003cString\\u003e] [-Force] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365SeleniumDownload\",\n        \"Description\":  \"Downloads the Selenium web driver files and deploys them to the specified destinations.\",\n        \"Params\":  [\n                       [\n                           \"RegressionSuiteAutomationTool\",\n                           \"Switch to specify if the Selenium files need to be installed in the Regression Suite Automation Tool folder.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"PerfSDK\",\n                           \"Switch to specify if the Selenium files need to be installed in the PerfSDK folder.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Kenny Saelen (@kennysaelen)\",\n        \"Synopsis\":  \"Downloads the Selenium web driver files and deploys them to the specified destinations.\",\n        \"Name\":  \"Invoke-D365SeleniumDownload\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365SeleniumDownload -RegressionSuiteAutomationTool -PerfSDK\\nThis will download the Selenium zip archives and extract the files into both the Regression Suite Automation Tool folder and the PerfSDK folder.\",\n        \"Syntax\":  \"Invoke-D365SeleniumDownload [[-RegressionSuiteAutomationTool]] [[-PerfSDK]] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365SqlScript\",\n        \"Description\":  \"Execute a SQL Script or a SQL Command against the D365FO SQL Server database\",\n        \"Params\":  [\n                       [\n                           \"FilePath\",\n                           \"Path to the file containing the SQL Script that you want executed\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Command\",\n                           \"SQL command that you want executed\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"TrustedConnection\",\n                           \"Switch to instruct the cmdlet whether the connection should be using Windows Authentication or not\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"NoPooling\",\n                           \"Should the connection use connection pooling or not\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"Invoke-D365SqlCmd\",\n        \"Author\":  \"Mötz Jensen (@splaxi)\",\n        \"Synopsis\":  \"Execute a SQL Script or a SQL Command\",\n        \"Name\":  \"Invoke-D365SqlScript\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365SqlScript -FilePath \\\"C:\\\\temp\\\\d365fo.tools\\\\DeleteUser.sql\\\"\\nThis will execute the \\\"C:\\\\temp\\\\d365fo.tools\\\\DeleteUser.sql\\\" against the registered SQL Server on the machine.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365SqlScript -Command \\\"DELETE FROM SALESTABLE WHERE RECID = 123456789\\\"\\nThis will execute \\\"DELETE FROM SALESTABLE WHERE RECID = 123456789\\\" against the registered SQL Server on the machine.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eInvoke-D365SqlScript -Command \\\"DELETE FROM SALESTABLE WHERE RECID = 123456789\\\" -NoPooling\\nThis will execute \\\"DELETE FROM SALESTABLE WHERE RECID = 123456789\\\" against the registered SQL Server on the machine.\\r\\nIt will not use connection pooling.\",\n        \"Syntax\":  \"Invoke-D365SqlScript [-FilePath] \\u003cString\\u003e [-DatabaseServer \\u003cString\\u003e] [-DatabaseName \\u003cString\\u003e] [-SqlUser \\u003cString\\u003e] [-SqlPwd \\u003cString\\u003e] [-TrustedConnection \\u003cBoolean\\u003e] [-EnableException] [-NoPooling] [\\u003cCommonParameters\\u003e]\\nInvoke-D365SqlScript [-Command] \\u003cString\\u003e [-DatabaseServer \\u003cString\\u003e] [-DatabaseName \\u003cString\\u003e] [-SqlUser \\u003cString\\u003e] [-SqlPwd \\u003cString\\u003e] [-TrustedConnection \\u003cBoolean\\u003e] [-EnableException] [-NoPooling] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365SysFlushAodCache\",\n        \"Description\":  \"Invoke the runnable class SysFlushAos to clear the AOD cache\",\n        \"Params\":  [\n                       [\n                           \"Url\",\n                           \"URL to the Dynamics 365 instance you want to clear the AOD cache on\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Invoke the SysFlushAos class\",\n        \"Name\":  \"Invoke-D365SysFlushAodCache\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365SysFlushAodCache\\nThis will a call against the default URL for the machine and\\r\\nhave it execute the SysFlushAOD class\",\n        \"Syntax\":  \"Invoke-D365SysFlushAodCache [[-Url] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365SysRunnerClass\",\n        \"Description\":  \"Makes it possible to call any runnable class directly from the browser, without worrying about the details\",\n        \"Params\":  [\n                       [\n                           \"ClassName\",\n                           \"The name of the class you want to execute\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Company\",\n                           \"The company for which you want to execute the class against\\nDefault value is: \\\"DAT\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:Company\"\n                       ],\n                       [\n                           \"Url\",\n                           \"The URL you want to execute against\\nDefault value is the Fully Qualified Domain Name registered on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:Url\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Start a browser session that executes SysRunnerClass\",\n        \"Name\":  \"Invoke-D365SysRunnerClass\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365SysRunnerClass -ClassName SysFlushAOD\\nWill execute the SysRunnerClass and have it execute the SysFlushAOD class and will run it against the \\\"DAT\\\" (default value) company\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365SysRunnerClass -ClassName SysFlushAOD -Company \\\"USMF\\\"\\nWill execute the SysRunnerClass and have it execute the SysFlushAOD class and will run it against the \\\"USMF\\\" company\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eInvoke-D365SysRunnerClass -ClassName SysFlushAOD -Url https://Test.cloud.onebox.dynamics.com\\nWill execute the SysRunnerClass and have it execute the SysFlushAOD class and will run it against the \\\"DAT\\\" company, on the https://Test.cloud.onebox.dynamics.com URL\",\n        \"Syntax\":  \"Invoke-D365SysRunnerClass [-ClassName] \\u003cString\\u003e [[-Company] \\u003cString\\u003e] [[-Url] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365TableBrowser\",\n        \"Description\":  \"Makes it possible to call the table browser for a given table directly from the web browser, without worrying about the details\",\n        \"Params\":  [\n                       [\n                           \"TableName\",\n                           \"The name of the table you want to see the rows for\",\n                           \"\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"Company\",\n                           \"The company for which you want to see the data from in the given table\\nDefault value is: \\\"DAT\\\"\",\n                           \"\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"$Script:Company\"\n                       ],\n                       [\n                           \"Url\",\n                           \"The URL you want to execute against\\nDefault value is the Fully Qualified Domain Name registered on the machine\",\n                           \"\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"$Script:Url\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Start a browser session that will show the table browser\",\n        \"Name\":  \"Invoke-D365TableBrowser\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365TableBrowser -TableName SalesTable\\nWill open the table browser and show all the records in Sales Table from the \\\"DAT\\\" company (default value).\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365TableBrowser -TableName SalesTable -Company \\\"USMF\\\"\\nWill open the table browser and show all the records in Sales Table from the \\\"USMF\\\" company.\",\n        \"Syntax\":  \"Invoke-D365TableBrowser [-TableName] \\u003cString\\u003e [[-Company] \\u003cString\\u003e] [[-Url] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365VisualStudioCompilerResultAnalyzer\",\n        \"Description\":  \"Analyze the Visual Studio compiler output log and generate an excel file contain worksheets per type: Errors, Warnings, Tasks\",\n        \"Tags\":  [\n                     \"Compiler\",\n                     \"Build\",\n                     \"Errors\",\n                     \"Warnings\",\n                     \"Tasks\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Module\",\n                           \"Name of the module that you want to work against\\nDefault value is \\\"*\\\" which will search for all modules\",\n                           \"ModuleName\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"OutputPath\",\n                           \"Path where you want the excel file (xlsx-file) saved to\\nDefault value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"SkipWarnings\",\n                           \"Instructs the cmdlet to skip warnings while analyzing the compiler output log file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"SkipTasks\",\n                           \"Instructs the cmdlet to skip tasks while analyzing the compiler output log file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the directory containing the installed package / module\\nDefault path is the same as the AOS service \\\"PackagesLocalDirectory\\\" directory\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Analyze the Visual Studio compiler output log\",\n        \"Name\":  \"Invoke-D365VisualStudioCompilerResultAnalyzer\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365VisualStudioCompilerResultAnalyzer\\nThis will analyse all compiler output log files generated from Visual Studio.\\nA result set example:\\nFile                                                            Filename\\r\\n----                                                            --------\\r\\nc:\\\\temp\\\\d365fo.tools\\\\ApplicationCommon-CompilerResults.xlsx     ApplicationCommon-CompilerResults.xlsx\\r\\nc:\\\\temp\\\\d365fo.tools\\\\ApplicationFoundation-CompilerResults.xlsx ApplicationFoundation-CompilerResults.xlsx\\r\\nc:\\\\temp\\\\d365fo.tools\\\\ApplicationPlatform-CompilerResults.xlsx   ApplicationPlatform-CompilerResults.xlsx\\r\\nc:\\\\temp\\\\d365fo.tools\\\\ApplicationSuite-CompilerResults.xlsx      ApplicationSuite-CompilerResults.xlsx\\r\\nc:\\\\temp\\\\d365fo.tools\\\\ApplicationWorkspaces-CompilerResults.xlsx ApplicationWorkspaces-CompilerResults.xlsx\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eInvoke-D365VisualStudioCompilerResultAnalyzer -SkipWarnings\\nThis will analyse all compiler output log files generated from Visual Studio.\\r\\nIt will exclude all warnings from the output.\\nA result set example:\\nFile                                                            Filename\\r\\n----                                                            --------\\r\\nc:\\\\temp\\\\d365fo.tools\\\\ApplicationCommon-CompilerResults.xlsx     ApplicationCommon-CompilerResults.xlsx\\r\\nc:\\\\temp\\\\d365fo.tools\\\\ApplicationFoundation-CompilerResults.xlsx ApplicationFoundation-CompilerResults.xlsx\\r\\nc:\\\\temp\\\\d365fo.tools\\\\ApplicationPlatform-CompilerResults.xlsx   ApplicationPlatform-CompilerResults.xlsx\\r\\nc:\\\\temp\\\\d365fo.tools\\\\ApplicationSuite-CompilerResults.xlsx      ApplicationSuite-CompilerResults.xlsx\\r\\nc:\\\\temp\\\\d365fo.tools\\\\ApplicationWorkspaces-CompilerResults.xlsx ApplicationWorkspaces-CompilerResults.xlsx\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eInvoke-D365VisualStudioCompilerResultAnalyzer -SkipTasks\\nThis will analyse all compiler output log files generated from Visual Studio.\\r\\nIt will exclude all tasks from the output.\\nA result set example:\\nFile                                                            Filename\\r\\n----                                                            --------\\r\\nc:\\\\temp\\\\d365fo.tools\\\\ApplicationCommon-CompilerResults.xlsx     ApplicationCommon-CompilerResults.xlsx\\r\\nc:\\\\temp\\\\d365fo.tools\\\\ApplicationFoundation-CompilerResults.xlsx ApplicationFoundation-CompilerResults.xlsx\\r\\nc:\\\\temp\\\\d365fo.tools\\\\ApplicationPlatform-CompilerResults.xlsx   ApplicationPlatform-CompilerResults.xlsx\\r\\nc:\\\\temp\\\\d365fo.tools\\\\ApplicationSuite-CompilerResults.xlsx      ApplicationSuite-CompilerResults.xlsx\\r\\nc:\\\\temp\\\\d365fo.tools\\\\ApplicationWorkspaces-CompilerResults.xlsx ApplicationWorkspaces-CompilerResults.xlsx\",\n        \"Syntax\":  \"Invoke-D365VisualStudioCompilerResultAnalyzer [[-Module] \\u003cString\\u003e] [[-OutputPath] \\u003cString\\u003e] [-SkipWarnings] [-SkipTasks] [[-PackageDirectory] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Invoke-D365WinRmCertificateRotation\",\n        \"Description\":  \"There is a scenario where you might need to update the certificate that is being used for WinRM on your Tier1 environment\\n\\n1 year after you deploy your Tier1 environment, the original WinRM certificate expires and then LCS will be unable to communicate with your Tier1 environment\",\n        \"Params\":  [\n                       [\n                           \"MachineName\",\n                           \"The DNS / Netbios name of the machine\\nThe default value is: \\\"$env:COMPUTERNAME\\\" which translates into the current name of the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$env:COMPUTERNAME\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Rotate the certificate used for WinRM\",\n        \"Name\":  \"Invoke-D365WinRmCertificateRotation\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365WinRmCertificateRotation\\nThis will update the certificate that is being used by WinRM.\\r\\nA new certificate is created with the current computer name.\\r\\nThe new certificate and its thumbprint will be configured for WinRM to use that going forward.\",\n        \"Syntax\":  \"Invoke-D365WinRmCertificateRotation [[-MachineName] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"New-D365Bacpac\",\n        \"Description\":  \"Takes care of all the details and steps that is needed to create a valid bacpac file to move between Tier 1 (onebox or Azure hosted) and Tier 2 (MS hosted), or vice versa\\n\\nSupports to create a raw bacpac file without prepping. Can be used to automate backup from Tier 2 (MS hosted) environment\",\n        \"Params\":  [\n                       [\n                           \"ExportModeTier1\",\n                           \"Switch to instruct the cmdlet that the export will be done against a classic SQL Server installation\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"ExportModeTier2\",\n                           \"Switch to instruct the cmdlet that the export will be done against an Azure SQL DB instance\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"BackupDirectory\",\n                           \"The path where to store the temporary backup file when the script needs to handle that\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"C:\\\\Temp\\\\d365fo.tools\\\\SqlBackups\"\n                       ],\n                       [\n                           \"NewDatabaseName\",\n                           \"The name for the database the script is going to create when doing the restore process\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:DatabaseName`_export\\\"\"\n                       ],\n                       [\n                           \"BacpacFile\",\n                           \"The path where you want the cmdlet to store the bacpac file that will be generated\",\n                           \"File\",\n                           false,\n                           \"false\",\n                           \"\\\"C:\\\\Temp\\\\d365fo.tools\\\\$DatabaseName.bacpac\\\"\"\n                       ],\n                       [\n                           \"CustomSqlFile\",\n                           \"The path to a custom sql server script file that you want executed against the database before it is exported\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"DiagnosticFile\",\n                           \"Path to where you want the export to output a diagnostics file to assist you in troubleshooting the export\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ExportOnly\",\n                           \"Switch to instruct the cmdlet to either just create a dump bacpac file or run the prepping process first\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"MaxParallelism\",\n                           \"Sets SqlPackage.exe\\u0027s degree of parallelism for concurrent operations running against a database. The default value is 8.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"8\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Rasmus Andersen (@ITRasmus)\",\n        \"Synopsis\":  \"Generate a bacpac file from a database\",\n        \"Name\":  \"New-D365Bacpac\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365InstallSqlPackage\\nYou should always install the latest version of the SqlPackage.exe, which is used by New-D365Bacpac.\\nThis will fetch the latest .Net Core Version of SqlPackage.exe and install it at \\\"C:\\\\temp\\\\d365fo.tools\\\\SqlPackage\\\".\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eNew-D365Bacpac -ExportModeTier1 -BackupDirectory c:\\\\Temp\\\\backup\\\\ -NewDatabaseName Testing1 -BacpacFile \\\"C:\\\\Temp\\\\Bacpac\\\\Testing1.bacpac\\\"\\nWill backup the \\\"AXDB\\\" database and restore is as \\\"Testing1\\\" again the localhost SQL Server.\\r\\nWill run the prepping process against the restored database.\\r\\nWill export a bacpac file to \\\"C:\\\\Temp\\\\Bacpac\\\\Testing1.bacpac\\\".\\r\\nWill delete the restored database.\\r\\nIt will use trusted connection (Windows authentication) while working against the SQL Server.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eNew-D365Bacpac -ExportModeTier2 -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd \\\"Password123\\\" -NewDatabaseName Testing1 -BacpacFile C:\\\\Temp\\\\Bacpac\\\\Testing1.bacpac\\nWill create a copy the db database on the dbserver1 in Azure.\\r\\nWill run the prepping process against the copy database.\\r\\nWill export a bacpac file.\\r\\nWill delete the copy database.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eNew-D365Bacpac -ExportModeTier2 -SqlUser User123 -SqlPwd \\\"Password123\\\" -NewDatabaseName Testing1 -BacpacFile \\\"C:\\\\Temp\\\\Bacpac\\\\Testing1.bacpac\\\"\\nNormally used for a Tier-2 export and preparation for Tier-1 import\\nWill create a copy of the registered D365 database on the registered D365 Azure SQL DB instance.\\r\\nWill run the prepping process against the copy database.\\r\\nWill export a bacpac file.\\r\\nWill delete the copy database.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eNew-D365Bacpac -ExportModeTier2 -SqlUser User123 -SqlPwd \\\"Password123\\\" -NewDatabaseName Testing1 -BacpacFile C:\\\\Temp\\\\Bacpac\\\\Testing1.bacpac -ExportOnly\\nWill export a bacpac file.\\r\\nThe bacpac should be able to restore back into the database without any preparing because it is coming from the environment from the beginning\\n-------------------------- EXAMPLE 6 --------------------------\\nPS C:\\\\\\u003eNew-D365Bacpac -ExportModeTier1 -BackupDirectory c:\\\\Temp\\\\backup\\\\ -NewDatabaseName Testing1 -BacpacFile \\\"C:\\\\Temp\\\\Bacpac\\\\Testing1.bacpac\\\" -DiagnosticFile \\\"C:\\\\temp\\\\ExportLog.txt\\\"\\nWill backup the \\\"AXDB\\\" database and restore is as \\\"Testing1\\\" again the localhost SQL Server.\\r\\nWill run the prepping process against the restored database.\\r\\nWill export a bacpac file to \\\"C:\\\\Temp\\\\Bacpac\\\\Testing1.bacpac\\\".\\r\\nWill delete the restored database.\\r\\nIt will use trusted connection (Windows authentication) while working against the SQL Server.\\nIt will output a diagnostic file to \\\"C:\\\\temp\\\\ExportLog.txt\\\".\\n-------------------------- EXAMPLE 7 --------------------------\\nPS C:\\\\\\u003eNew-D365Bacpac -ExportModeTier1 -BackupDirectory c:\\\\Temp\\\\backup\\\\ -NewDatabaseName Testing1 -BacpacFile \\\"C:\\\\Temp\\\\Bacpac\\\\Testing1.bacpac\\\" -MaxParallelism 32\\nWill backup the \\\"AXDB\\\" database and restore is as \\\"Testing1\\\" again the localhost SQL Server.\\r\\nWill run the prepping process against the restored database.\\r\\nWill export a bacpac file to \\\"C:\\\\Temp\\\\Bacpac\\\\Testing1.bacpac\\\".\\r\\nWill delete the restored database.\\r\\nIt will use trusted connection (Windows authentication) while working against the SQL Server.\\nIt will use 32 connections against the database server while generating the bacpac file.\",\n        \"Syntax\":  \"New-D365Bacpac [-ExportModeTier2] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [-SqlUser] \\u003cString\\u003e [-SqlPwd] \\u003cString\\u003e [[-NewDatabaseName] \\u003cString\\u003e] [[-BacpacFile] \\u003cString\\u003e] [[-CustomSqlFile] \\u003cString\\u003e] [-DiagnosticFile \\u003cString\\u003e] [-ExportOnly] [-MaxParallelism \\u003cInt32\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [\\u003cCommonParameters\\u003e]\\nNew-D365Bacpac [-ExportModeTier1] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [[-BackupDirectory] \\u003cString\\u003e] [[-NewDatabaseName] \\u003cString\\u003e] [[-BacpacFile] \\u003cString\\u003e] [[-CustomSqlFile] \\u003cString\\u003e] [-DiagnosticFile \\u003cString\\u003e] [-ExportOnly] [-MaxParallelism \\u003cInt32\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"New-D365CAReport\",\n        \"Description\":  \"A cmdlet that wraps some of the cumbersome work into a streamlined process\",\n        \"Params\":  [\n                       [\n                           \"OutputPath\",\n                           \"Path where you want the CAR file (xlsx-file) saved to\\nDefault value is: \\\"c:\\\\temp\\\\d365fo.tools\\\\CAReport.xlsx\\\"\",\n                           \"Path,File\",\n                           false,\n                           \"false\",\n                           \"(Join-Path $Script:DefaultTempPath \\\"CAReport.xlsx\\\")\"\n                       ],\n                       [\n                           \"Module\",\n                           \"Name of the Module to analyse\",\n                           \"ModuleName,Package\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Model\",\n                           \"Name of the Model to analyse\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"SuffixWithModule\",\n                           \"Instruct the cmdlet to append the module name as a suffix to the desired output file name\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the AOS service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:PackageDirectory\\\\bin\\\"\"\n                       ],\n                       [\n                           \"MetaDataDir\",\n                           \"The path to the meta data directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:MetaDataDir\\\"\"\n                       ],\n                       [\n                           \"XmlLog\",\n                           \"Path where you want to store the Xml log output generated from the best practice analyser\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"(Join-Path $Script:DefaultTempPath \\\"BPCheckLogcd.xml\\\")\"\n                       ],\n                       [\n                           \"PackagesRoot\",\n                           \"Instructs the cmdlet to use binary metadata\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"The path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\CAReport\\\")\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Tommy Skaue (@Skaue)\",\n        \"Synopsis\":  \"Generate the Customization\\u0027s Analysis Report (CAR)\",\n        \"Name\":  \"New-D365CAReport\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eNew-D365CAReport -module \\\"ApplicationSuite\\\" -model \\\"MyOverLayerModel\\\"\\nThis will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module.\\r\\nIt will use the default value for the OutputPath parameter, which is \\\"c:\\\\temp\\\\d365fo.tools\\\\CAReport.xlsx\\\".\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eNew-D365CAReport -OutputPath \\\"c:\\\\temp\\\\CAReport.xlsx\\\" -module \\\"ApplicationSuite\\\" -model \\\"MyOverLayerModel\\\"\\nThis will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module.\\r\\nIt will use the \\\"c:\\\\temp\\\\CAReport.xlsx\\\" value for the OutputPath parameter.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eNew-D365CAReport -module \\\"ApplicationSuite\\\" -model \\\"MyOverLayerModel\\\" -SuffixWithModule\\nThis will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module.\\r\\nIt will use the default value for the OutputPath parameter, which is \\\"c:\\\\temp\\\\d365fo.tools\\\\CAReport.xlsx\\\".\\r\\nIt will append the module name to the desired output file, which will then be \\\"c:\\\\temp\\\\d365fo.tools\\\\CAReport-ApplicationSuite.xlsx\\\".\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eNew-D365CAReport -OutputPath \\\"c:\\\\temp\\\\CAReport.xlsx\\\" -module \\\"ApplicationSuite\\\" -model \\\"MyOverLayerModel\\\" -PackagesRoot\\nThis will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module.\\r\\nIt will use the binary metadata to look for the module and model.\\r\\nIt will use the \\\"c:\\\\temp\\\\CAReport.xlsx\\\" value for the OutputPath parameter.\",\n        \"Syntax\":  \"New-D365CAReport [[-OutputPath] \\u003cString\\u003e] [-Module] \\u003cString\\u003e [-Model] \\u003cString\\u003e [-SuffixWithModule] [[-BinDir] \\u003cString\\u003e] [[-MetaDataDir] \\u003cString\\u003e] [[-XmlLog] \\u003cString\\u003e] [-PackagesRoot] [[-LogPath] \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"New-D365EntraIntegration\",\n        \"Description\":  \"Enable the Microsoft Entra ID integration by executing some of the steps described in https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/dev-tools/secure-developer-vm#external-integrations.\\nThe integration can either be enabled with an existing certificate or a new self-signed certificate can be created.\\nIf a new certificate is created and the integration is also to be enabled on other environments with the same certificate, a certificate password must be specified in order to create a certificate private key file.\\n\\nThe steps executed are:\\n\\n- 1) Create a self-signed certificate and save it to Desktop or use a provided certificate.\\n- 2) Install the certificate to the \\\"LocalMachine\\\" certificate store.\\n- 3) Grant NetworkService READ permission to the certificate (only on cloud-hosted environments).\\n- 4) Update the web.config with the application ID and the thumbprint of the certificate.\\n- 5) Add the application registration to the WIF config.\\n- 6) Clear cached LCS configuration in AxDB.\\n- 7) Restart the IIS service.\\n\\nTo execute the steps, the id of an Azure application must be provided. The application must have the following API permissions:\\n\\n- Dynamics ERP - This permission is required to access finance and operations environments.\\n- Microsoft Graph (User.Read.All and Group.Read.All permissions of the Application type).\\n- Dynamics Lifecylce service (permission of type Delegated)\\n\\nThe URL of the finance and operations environment must also be added to the RedirectURI in the Authentication section of the Azure application.\\nFinally, after running the cmdlet, if a new certificate was created, it must be uploaded to the Azure application.\",\n        \"Params\":  [\n                       [\n                           \"ClientId\",\n                           \"The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal.\\r\\nIt is assumed that an application with this id already exists in Azure.\",\n                           \"AppId\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ExistingCertificateFile\",\n                           \"The path to a certificate file. If this parameter is provided, the cmdlet will not create a new certificate.\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ExistingCertificatePrivateKeyFile\",\n                           \"The path to a certificate private key file.\\r\\nIf this parameter is not provided, the certificate can be installed to the certificate store, but the NetworkService cannot be granted READ permission.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"CertificateName\",\n                           \"The name for the certificate. By default, it is named \\\"CHEAuth\\\".\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"CHEAuth\"\n                       ],\n                       [\n                           \"CertificateExpirationYears\",\n                           \"The number of years the certificate is valid. By default, it is valid for 2 years.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"2\"\n                       ],\n                       [\n                           \"NewCertificateFile\",\n                           \"The path to the certificate file that will be created. By default, it is created on the Desktop of the current user.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$env:USERPROFILE\\\\Desktop\\\\$CertificateName.cer\\\"\"\n                       ],\n                       [\n                           \"NewCertificatePrivateKeyFile\",\n                           \"The path to the certificate private key file that will be created. By default, it is created on the Desktop of the current user.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$env:USERPROFILE\\\\Desktop\\\\$CertificateName.pfx\\\"\"\n                       ],\n                       [\n                           \"CertificatePassword\",\n                           \"The password for the certificate private key file.\\r\\nIf not provided when creating a new certificate, no private key file will be created.\\r\\nIf not provided when using an existing certificate, the private key file cannot be installed.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Forces the execution of some of the steps. For example, if a certificate with the same name already exists, it will be deleted and recreated.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"WhatIf\",\n                           \"Executes the cmdlet until the first operation that would change the state of the system, without executing that operation.\\r\\nSubsequent operations are likely to fail.\\r\\nThis is currently not fully implemented and should not be used.\",\n                           \"wi\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Confirm\",\n                           \"Prompts for confirmation before each operation of the cmdlet that changes the state of the system.\",\n                           \"cf\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Øystein Brenna (@oysbre)\",\n        \"Synopsis\":  \"Enable the Microsoft Entra ID integration on a cloud hosted environment (CHE).\",\n        \"Name\":  \"New-D365EntraIntegration\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eNew-D365EntraIntegration -ClientId e70cac82-6a7c-4f9e-a8b9-e707b961e986\\nEnables the Entra ID integration with a new self-signed certificate named \\\"CHEAuth\\\" which expires after 2 years.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eNew-D365EntraIntegration -ClientId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -CertificateName \\\"SelfsignedCert\\\"\\nEnables the Entra ID integration with a new self-signed certificate with the name \\\"Selfsignedcert\\\" that expires after 2 years.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eNew-D365EntraIntegration -AppId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -CertificateName \\\"SelfsignedCert\\\" -CertificateExpirationYears 1\\nEnables the Entra ID integration with a new self-signed certificate with the name \\\"SelfsignedCert\\\" that expires after 1 year.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003e$securePassword = Read-Host -AsSecureString -Prompt \\\"Enter the certificate password\\\"\\nPS C:\\\\\\u003e New-D365EntraIntegration -AppId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -CertificatePassword $securePassword\\nEnables the Entra ID integration with a new self-signed certificate with the name \\\"CHEAuth\\\" that expires after 2 years, using the provided password to generate the private key of the certificate.\\r\\nThe certificate file and the private key file are saved to the Desktop of the current user.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003e$securePassword = Read-Host -AsSecureString -Prompt \\\"Enter the certificate password\\\"\\nPS C:\\\\\\u003e New-D365EntraIntegration -AppId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -ExistingCertificateFile \\\"C:\\\\Temp\\\\SelfsignedCert.cer\\\" -ExistingCertificatePrivateKeyFile \\\"C:\\\\Temp\\\\SelfsignedCert.pfx\\\" \\r\\n-CertificatePassword $securePassword\\nEnables the Entra ID integration with the certificate file \\\"C:\\\\Temp\\\\SelfsignedCert.cer\\\", the private key file \\\"C:\\\\Temp\\\\SelfsignedCert.pfx\\\" and the provided password to install it.\",\n        \"Syntax\":  \"New-D365EntraIntegration -ClientId \\u003cString\\u003e [-CertificateName \\u003cString\\u003e] [-CertificateExpirationYears \\u003cInt32\\u003e] [-NewCertificateFile \\u003cString\\u003e] [-NewCertificatePrivateKeyFile \\u003cString\\u003e] [-CertificatePassword \\u003cSecureString\\u003e] [-Force] [-WhatIf] [-Confirm] [\\u003cCommonParameters\\u003e]\\nNew-D365EntraIntegration -ClientId \\u003cString\\u003e -ExistingCertificateFile \\u003cString\\u003e [-ExistingCertificatePrivateKeyFile \\u003cString\\u003e] [-CertificatePassword \\u003cSecureString\\u003e] [-Force] [-WhatIf] [-Confirm] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"New-D365ISVLicense\",\n        \"Description\":  \"Create a deployable package with a license file inside\",\n        \"Params\":  [\n                       [\n                           \"LicenseFile\",\n                           \"Path to the license file that you want to have inside a deployable package\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Path\",\n                           \"Path to the template zip file for creating a deployable package with a license file\\nDefault path is the same as the aos service \\\"PackagesLocalDirectory\\\\bin\\\\CustomDeployablePackage\\\\ImportISVLicense.zip\\\"\",\n                           \"Template\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDirTools\\\\CustomDeployablePackage\\\\ImportISVLicense.zip\\\"\"\n                       ],\n                       [\n                           \"OutputPath\",\n                           \"Path where you want the generated deployable package stored\\nDefault value is: \\\"C:\\\\temp\\\\d365fo.tools\\\\ISVLicense.zip\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"C:\\\\temp\\\\d365fo.tools\\\\ISVLicense.zip\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@splaxi)\",\n        \"Synopsis\":  \"Create a license deployable package\",\n        \"Name\":  \"New-D365ISVLicense\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eNew-D365ISVLicense -LicenseFile \\\"C:\\\\temp\\\\ISVLicenseFile.txt\\\"\\nThis will take the \\\"C:\\\\temp\\\\ISVLicenseFile.txt\\\" file and locate the \\\"ImportISVLicense.zip\\\" template file under the \\\"PackagesLocalDirectory\\\\bin\\\\CustomDeployablePackage\\\\\\\".\\r\\nIt will extract the \\\"ImportISVLicense.zip\\\", load the ISVLicenseFile.txt and compress (zip) the files into a deployable package.\\r\\nThe package will be exported to \\\"C:\\\\temp\\\\d365fo.tools\\\\ISVLicense.zip\\\"\",\n        \"Syntax\":  \"New-D365ISVLicense [-LicenseFile] \\u003cString\\u003e [-Path \\u003cString\\u003e] [-OutputPath \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"New-D365ModuleToRemove\",\n        \"Description\":  \"Create a new ModuleToRemove.txt file based on a list of module names\",\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the ModuleToRemove.txt file\",\n                           \"Folder\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Modules\",\n                           \"The array with all the module names that you want to fill into the ModuleToRemove.txt file\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Florian Hopfner (@FH-Inway)\",\n        \"Synopsis\":  \"Create a new ModuleToRemove.txt file\",\n        \"Name\":  \"New-D365ModuleToRemove\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eNew-D365ModuleToRemove -Path C:\\\\Temp -Modules \\\"MyRemovedModule1\\\",\\\"MySecondRemovedModule\\\"\\nThis will create a new ModuleToRemove.txt file and fill in \\\"MyRemovedModule1\\\" and \\\"MySecondRemovedModule\\\" as the modules to remove.\\r\\nThe new file is stored at \\\"C:\\\\Temp\\\\ModuleToRemove.txt\\\"\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eNew-D365ModuleToRemove -Path C:\\\\Temp -Modules \\\"MyRemovedModule1\\\",\\\"MySecondRemovedModule\\\" | Add-D365ModuleToRemove -DeployablePackage C:\\\\Temp\\\\DeployablePackage.zip\\nThis will create a new ModuleToRemove.txt file and fill in \\\"MyRemovedModule1\\\" and \\\"MySecondRemovedModule\\\" as the modules to remove. The file is then added to the \\\"C:\\\\Temp\\\\DeployablePackage.zip\\\" \\r\\ndeployable package.\",\n        \"Syntax\":  \"New-D365ModuleToRemove [-Path] \\u003cString\\u003e [-Modules] \\u003cString[]\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"New-D365TopologyFile\",\n        \"Description\":  \"Build a new topology file based on a template and update the ServiceModelList\",\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the template topology file\",\n                           \"File\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Services\",\n                           \"The array with all the service names that you want to fill into the topology file\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"NewPath\",\n                           \"Path to where you want to save the new file after it has been created\",\n                           \"NewFile\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Create a new topology file\",\n        \"Name\":  \"New-D365TopologyFile\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eNew-D365TopologyFile -Path C:\\\\Temp\\\\DefaultTopologyData.xml -Services \\\"ALMService\\\",\\\"AOSService\\\",\\\"BIService\\\" -NewPath C:\\\\temp\\\\CurrentTopology.xml\\nThis will read the \\\"DefaultTopologyData.xml\\\" file and fill in \\\"ALMService\\\",\\\"AOSService\\\" and \\\"BIService\\\"\\r\\nas the services in the ServiceModelList tag. The new file is stored at \\\"C:\\\\temp\\\\CurrentTopology.xml\\\"\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003e$Services = @(Get-D365InstalledService | ForEach-Object {$_.Servicename})\\nPS C:\\\\\\u003e New-D365TopologyFile -Path C:\\\\Temp\\\\DefaultTopologyData.xml -Services $Services -NewPath C:\\\\temp\\\\CurrentTopology.xml\\nThis will get all the services already installed on the machine. Afterwards the list is piped\\r\\nto New-D365TopologyFile where all services are import into the new topology file that is stored at \\\"C:\\\\temp\\\\CurrentTopology.xml\\\"\",\n        \"Syntax\":  \"New-D365TopologyFile [-Path] \\u003cString\\u003e [-Services] \\u003cString[]\\u003e [-NewPath] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Publish-D365SsrsReport\",\n        \"Description\":  \"Deploy SSRS Report to SQL Server Reporting Services\",\n        \"Tags\":  [\n                     \"SSRS\",\n                     \"Report\",\n                     \"Reports\",\n                     \"Deploy\",\n                     \"Publish\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Module\",\n                           \"Name of the module that you want to works against\\nAccepts an array of strings\\nDefault value is \\\"*\\\" and will work against all modules loaded on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"ReportName\",\n                           \"Name of the report that you want to deploy\\nDefault value is \\\"*\\\" and will deploy all reports from the module(s) that you speficied\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"*\"\n                       ],\n                       [\n                           \"LogFile\",\n                           \"Path to the file that should contain the logging information\\nDefault value is \\\"c:\\\\temp\\\\d365fo.tools\\\\AxReportDeployment.log\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"(Join-Path $Script:DefaultTempPath \\\"AxReportDeployment.log\\\")\"\n                       ],\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the PackagesLocalDirectory\\nDefault path is the same as the AOS Service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ],\n                       [\n                           \"ToolsBasePath\",\n                           \"Base path to the folder containing the needed PowerShell manifests that the cmdlet utilizes\\nDefault path is the same as the AOS Service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ],\n                       [\n                           \"ReportServerIp\",\n                           \"IP Address of the server that has SQL Reporting Services installed\\nDefault value is \\\"127.0.01\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"127.0.0.1\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Deploy Report\",\n        \"Name\":  \"Publish-D365SsrsReport\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003ePublish-D365SsrsReport -Module ApplicationSuite -ReportName TaxVatRegister.Report\\nThis will deploy the report which is named \\\"TaxVatRegister.Report\\\".\\r\\nThe cmdlet will look for the report inside the ApplicationSuite module.\\r\\nThe cmdlet will be using the default 127.0.0.1 while deploying the report.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003ePublish-D365SsrsReport -Module ApplicationSuite -ReportName *\\nThis will deploy the all reports from the ApplicationSuite module.\\r\\nThe cmdlet will be using the default 127.0.0.1 while deploying the report.\",\n        \"Syntax\":  \"Publish-D365SsrsReport [[-Module] \\u003cString[]\\u003e] [[-ReportName] \\u003cString[]\\u003e] [[-LogFile] \\u003cString\\u003e] [[-PackageDirectory] \\u003cString\\u003e] [[-ToolsBasePath] \\u003cString\\u003e] [[-ReportServerIp] \\u003cString[]\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Publish-D365WebResources\",\n        \"Description\":  \"Deploys the Dynamics 365 for Finance and Operations web resources to the AOS service web root path.\",\n        \"Params\":  [\n                       [\n                           \"PackageDirectory\",\n                           \"Path to the package directory containing the web resources.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:PackageDirectory\"\n                       ],\n                       [\n                           \"AosServiceWebRootPath\",\n                           \"Path to the AOS service web root path.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:AOSPath\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Florian Hopfner (@FH-Inway)\",\n        \"Synopsis\":  \"Deploy web resources\",\n        \"Name\":  \"Publish-D365WebResources\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003ePublish-D365WebResources\\nThis will deploy the web resources to the AOS service web root path.\",\n        \"Syntax\":  \"Publish-D365WebResources [[-PackageDirectory] \\u003cPathDirectoryParameter\\u003e] [[-AosServiceWebRootPath] \\u003cPathDirectoryParameter\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Register-D365AzureStorageConfig\",\n        \"Description\":  \"Register all Azure Storage Configurations\",\n        \"Tags\":  [\n                     \"Configuration\",\n                     \"Azure\",\n                     \"Storage\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"ConfigStorageLocation\",\n                           \"Parameter used to instruct where to store the configuration objects\\nThe default value is \\\"User\\\" and this will store all configuration for the active user\\nValid options are:\\r\\n\\\"User\\\"\\r\\n\\\"System\\\"\\n\\\"System\\\" will store the configuration as default for all users, so they can access the configuration objects\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"User\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Register Azure Storage Configurations\",\n        \"Name\":  \"Register-D365AzureStorageConfig\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eRegister-D365AzureStorageConfig -ConfigStorageLocation \\\"System\\\"\\nThis will store all Azure Storage Configurations as defaults for all users on the machine.\",\n        \"Syntax\":  \"Register-D365AzureStorageConfig [[-ConfigStorageLocation] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Remove-D365BroadcastMessageConfig\",\n        \"Description\":  \"Remove a broadcast message configuration from the configuration store\",\n        \"Tags\":  [\n                     \"Servicing\",\n                     \"Broadcast\",\n                     \"Message\",\n                     \"Users\",\n                     \"Environment\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"ClientId\",\n                     \"ClientSecret\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"Name of the broadcast message configuration you want to remove from the configuration store\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Temporary\",\n                           \"Instruct the cmdlet to only temporarily remove the broadcast message configuration from the configuration store\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Remove broadcast message configuration\",\n        \"Name\":  \"Remove-D365BroadcastMessageConfig\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eRemove-D365BroadcastMessageConfig -Name \\\"UAT\\\"\\nThis will remove the broadcast message configuration name \\\"UAT\\\" from the machine.\",\n        \"Syntax\":  \"Remove-D365BroadcastMessageConfig [-Name] \\u003cString\\u003e [-Temporary] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Remove-D365Database\",\n        \"Description\":  \"Removes a database. By default, if no other database is specified, the AxDB database will be removed.\",\n        \"Params\":  [\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Force\",\n                           \"This parameter will suppress the confirmation prompt. It can be used as an alternative to -Confirm:$false\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"WhatIf\",\n                           \"This parameter will simulate the actions of the command. No changes will be made.\",\n                           \"wi\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Confirm\",\n                           \"This parameter will prompt you for confirmation before executing steps of the command that have a medium impact.\",\n                           \"cf\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Removes a database\",\n        \"Name\":  \"Remove-D365Database\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eRemove-D365Database\\nThis will remove the \\\"AxDB\\\" database from the default SQL Server instance that is registered on the machine.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eRemove-D365Database -DatabaseName \\\"ExportClone\\\"\\nThis will remove the \\\"ExportClone\\\" from the default SQL Server instance that is registered on the machine.\",\n        \"Syntax\":  \"Remove-D365Database [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [-EnableException] [-Force] [-WhatIf] [-Confirm] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Remove-D365LcsAssetFile\",\n        \"Description\":  \"Delete asset from the LCS project Asset Library\",\n        \"Params\":  [\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\\r\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiProjectId\"\n                       ],\n                       [\n                           \"AssetId\",\n                           \"LCS Id of the file that you are looking for\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\\r\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"Token\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiBearerToken\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\\r\\nDefault value can be configured using Set-D365LcsApiConfig\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:LcsApiLcsApiUri\"\n                       ],\n                       [\n                           \"RetryTimeout\",\n                           \"The retry timeout, before the cmdlet should quit retrying based on the 429 status code\\nNeeds to be provided in the timspan notation:\\r\\n\\\"hh:mm:ss\\\"\\nhh is the number of hours, numerical notation only\\r\\nmm is the number of minutes\\r\\nss is the numbers of seconds\\nEach section of the timeout has to valid, e.g.\\r\\nhh can maximum be 23\\r\\nmm can maximum be 59\\r\\nss can maximum be 59\\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"00:00:00\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Oleksandr Nikolaiev (@onikolaiev)\",\n        \"Synopsis\":  \"Delete asset from the LCS project Asset Library\",\n        \"Name\":  \"Remove-D365LcsAssetFile\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eRemove-D365LcsAssetFile -ProjectId 123456789 -BearerToken \\\"JldjfafLJdfjlfsalfd...\\\" -LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\" -AssetId \\\"812bcb0e-23fb-476d-8a92-985f20a704b9\\\"\\nThis will delete the Asset file from the LCS Asset Library.\\r\\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\\r\\nThe request will authenticate with the BearerToken \\\"JldjfafLJdfjlfsalfd...\\\".\\r\\nThe http request will be going to the LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\" (NON-EUROPE).\",\n        \"Syntax\":  \"Remove-D365LcsAssetFile [[-ProjectId] \\u003cInt32\\u003e] [-AssetId] \\u003cString\\u003e [[-BearerToken] \\u003cString\\u003e] [[-LcsApiUri] \\u003cString\\u003e] [[-RetryTimeout] \\u003cTimeSpan\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Remove-D365Model\",\n        \"Description\":  \"Remove a model from a Dynamics 365 for Finance \\u0026 Operations environment\",\n        \"Tags\":  [\n                     \"ModelUtil\",\n                     \"Axmodel\",\n                     \"Model\",\n                     \"Remove\",\n                     \"Delete\",\n                     \"Source Control\",\n                     \"Vsts\",\n                     \"Azure DevOps\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Model\",\n                           \"Name of the model that you want to work against\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the AOS service PackagesLocalDirectory\\\\bin\\nDefault value is fetched from the current configuration on the machine\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:PackageDirectory\\\\bin\\\"\"\n                       ],\n                       [\n                           \"MetaDataDir\",\n                           \"The path to the meta data directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:MetaDataDir\\\"\"\n                       ],\n                       [\n                           \"DeleteFolders\",\n                           \"Instruct the cmdlet to delete the model folder\\nThis is useful when you are trying to clean up the folders in your source control / branch\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Remove a model from Dynamics 365 for Finance \\u0026 Operations\",\n        \"Name\":  \"Remove-D365Model\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eRemove-D365Model -Model CustomModelName\\nThis will remove the \\\"CustomModelName\\\" model from the D365FO environment.\\r\\nIt will NOT remove the folders inside the PackagesLocalDirectory location.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eRemove-D365Model -Model CustomModelName -DeleteFolders\\nThis will remove the \\\"CustomModelName\\\" model from the D365FO environment.\\r\\nIt will remove the folders inside the PackagesLocalDirectory location.\\r\\nThis is helpful when dealing with source control and you want to remove the model entirely.\",\n        \"Syntax\":  \"Remove-D365Model [-Model] \\u003cString\\u003e [[-BinDir] \\u003cString\\u003e] [[-MetaDataDir] \\u003cString\\u003e] [-DeleteFolders] [-ShowOriginalProgress] [-OutputCommandOnly] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Remove-D365User\",\n        \"Description\":  \"Deletes the user from the database, including security configuration\",\n        \"Params\":  [\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"Email\",\n                           \"The search string to select which user(s) should be updated.\\nYou have to specific the explicit email address of the user you want to remove\\nThe cmdlet will not be able to delete the ADMIN user, this is to prevent you\\r\\nfrom being locked out of the system.\",\n                           \"\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Rasmus Andersen (@ITRasmus)\",\n        \"Synopsis\":  \"Delete an user from the environment\",\n        \"Name\":  \"Remove-D365User\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eRemove-D365User -Email \\\"Claire@contoso.com\\\"\\nThis will move all security and user details from the user with the email address\\r\\n\\\"Claire@contoso.com\\\"\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365User -Email *contoso.com | Remove-D365User\\nThis will first get all users from the database that matches the *contoso.com\\r\\nsearch and pipe their emails to Remove-D365User for it to delete them.\",\n        \"Syntax\":  \"Remove-D365User [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [-Email] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Rename-D365ComputerName\",\n        \"Description\":  \"When doing development on-prem, there is as need for changing the Computername.\\nFunction both changes Computername and SSRS Configuration\",\n        \"Params\":  [\n                       [\n                           \"NewName\",\n                           \"The new name for the computer\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"SSRSReportDatabase\",\n                           \"Name of the SSRS reporting database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"DynamicsAxReportServer\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"LogPath\",\n                           \"The path where the log file(s) will be saved\\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\",\n                           \"LogDir\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"Logs\\\\RsConfig\\\")\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OutputCommandOnly\",\n                           \"Instruct the cmdlet to only output the command that you would have to execute by hand\\nWill include full path to the executable and the needed parameters based on your selection\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Rasmus Andersen (@ITRasmus)\",\n        \"Synopsis\":  \"Function for renaming computer.\\nRenames Computer and changes the SSRS Configration\",\n        \"Name\":  \"Rename-D365ComputerName\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eRename-D365ComputerName -NewName \\\"Demo-8.1\\\" -SSRSReportDatabase \\\"ReportServer\\\"\\nThis will rename the local machine to the \\\"Demo-8.1\\\" as the new Windows machine name.\\r\\nIt will update the registration inside the SQL Server Reporting Services configuration to handle the new name of the machine.\",\n        \"Syntax\":  \"Rename-D365ComputerName [-NewName] \\u003cString\\u003e [[-SSRSReportDatabase] \\u003cString\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [[-LogPath] \\u003cString\\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Rename-D365Instance\",\n        \"Description\":  \"The Rename function, changes the config values used by a D365FO dev box for identifying its name. Standard it is called \\u0027usnconeboxax1aos\\u0027\",\n        \"Params\":  [\n                       [\n                           \"NewName\",\n                           \"The new name wanted for the D365FO instance\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"AosServiceWebRootPath\",\n                           \"Path to the webroot folder for the AOS service \\u0027Default value : C:\\\\AOSService\\\\Webroot\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:AOSPath\"\n                       ],\n                       [\n                           \"IISServerApplicationHostConfigFile\",\n                           \"Path to the IISService Application host file, [Where the binding configurations is stored] \\u0027Default value : C:\\\\Windows\\\\System32\\\\inetsrv\\\\Config\\\\applicationHost.config\\u0027\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:IISHostFile\"\n                       ],\n                       [\n                           \"HostsFile\",\n                           \"Place of the host file on the current system [Local DNS record] \\u0027 Default value C:\\\\Windows\\\\System32\\\\drivers\\\\etc\\\\hosts\\u0027\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:Hosts\"\n                       ],\n                       [\n                           \"BackupExtension\",\n                           \"Backup name for all the files that are changed\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"bak\"\n                       ],\n                       [\n                           \"MRConfigFile\",\n                           \"Path to the Financial Reporter (Management Reporter) configuration file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:MRConfigFile\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Rasmus Andersen (@ITRasmus)\",\n        \"Synopsis\":  \"Rename as D365FO Demo/Dev box\",\n        \"Name\":  \"Rename-D365Instance\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eRename-D365Instance -NewName \\\"Demo1\\\"\\nThis will rename the D365 for Finance \\u0026 Operations instance to \\\"Demo1\\\".\\r\\nThis IIS will be restarted while doing it.\",\n        \"Syntax\":  \"Rename-D365Instance [-NewName] \\u003cString\\u003e [[-AosServiceWebRootPath] \\u003cString\\u003e] [[-IISServerApplicationHostConfigFile] \\u003cString\\u003e] [[-HostsFile] \\u003cString\\u003e] [[-BackupExtension] \\u003cString\\u003e] [[-MRConfigFile] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Repair-D365BacpacModelFile\",\n        \"Description\":  \"As the backend of the Azure SQL infrastructure keeps evolving, the bacpac file can contain invalid instructions while we are trying to import into a local SQL Server installation on a Tier1 environment\",\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the bacpac model file that you want to work against\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"OutputPath\",\n                           \"Path to where the repaired model file should be placed\\nThe default value is going to create a file next to the Path (input) file, with the \\u0027-edited\\u0027 name appended to it\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"PathRepairSimple\",\n                           \"Path to the json file, that contains all the instructions to be executed in the \\\"Simple\\\" section\\nThe default json file is part of the module, and can be located with the below command:\\r\\nexplorer.exe $(Join-Path -Path $(Split-Path -Path (Get-Module d365fo.tools -ListAvailable)[0].Path -Parent) -ChildPath \\\"internal\\\\misc\\\")\\r\\n- Look for the \\\"RepairBacpac.Simple.json\\\" file\\nOr you can see the latest version, online, inside the github repository: https://github.com/d365collaborative/d365fo.tools/tree/master/d365fo.tools/internal/misc/RepairBacpac.Simple.json\\nSimple means, that we can remove complex elements, based on some basic logic. E.g.\\n{\\r\\n\\\"Search\\\": \\\"*\\u003cElement Type=\\\\\\\"SqlPermissionStatement\\\\\\\"*ms_db_configreader*\\\",\\r\\n\\\"End\\\": \\\"*\\u003c/Element\\u003e*\\\"\\r\\n}\\n\\\"*\\u003cElement Type=\\\\\\\"SqlPermissionStatement\\\\\\\"*ms_db_configreader*\\\" can identify below, and together with \\\"*\\u003c/Element\\u003e*\\\" - we know when to stop.\\n\\u003cElement Type=\\\"SqlPermissionStatement\\\" Name=\\\"[Grant.Delete.Object].[ms_db_configreader].[dbo].[dbo].[AutotuneBase]\\\"\\u003e\\r\\n\\u003cProperty Name=\\\"Permission\\\" Value=\\\"4\\\" /\\u003e\\r\\n\\u003cRelationship Name=\\\"Grantee\\\"\\u003e\\r\\n\\u003cEntry\\u003e\\r\\n\\u003cReferences Name=\\\"[ms_db_configreader]\\\" /\\u003e\\r\\n\\u003c/Entry\\u003e\\r\\n\\u003c/Relationship\\u003e\\r\\n\\u003cRelationship Name=\\\"Grantor\\\"\\u003e\\r\\n\\u003cEntry\\u003e\\r\\n\\u003cReferences ExternalSource=\\\"BuiltIns\\\" Name=\\\"[dbo]\\\" /\\u003e\\r\\n\\u003c/Entry\\u003e\\r\\n\\u003c/Relationship\\u003e\\r\\n\\u003cRelationship Name=\\\"SecuredObject\\\"\\u003e\\r\\n\\u003cEntry\\u003e\\r\\n\\u003cReferences Name=\\\"[dbo].[AutotuneBase]\\\" /\\u003e\\r\\n\\u003c/Entry\\u003e\\r\\n\\u003c/Relationship\\u003e\\r\\n\\u003c/Element\\u003e\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$script:ModuleRoot\\\\internal\\\\misc\\\\RepairBacpac.Simple.json\\\"\"\n                       ],\n                       [\n                           \"PathRepairQualifier\",\n                           \"Path to the json file, that contains all the instructions to be executed in the \\\"Qualifier\\\" section\\nThe default json file is part of the module, and can be located with the below command:\\r\\nexplorer.exe $(Join-Path -Path $(Split-Path -Path (Get-Module d365fo.tools -ListAvailable)[0].Path -Parent) -ChildPath \\\"internal\\\\misc\\\")\\r\\n- Look for the \\\"RepairBacpac.Qualifier.json\\\" file\\nOr you can see the latest version, online, inside the github repository: https://github.com/d365collaborative/d365fo.tools/tree/master/d365fo.tools/internal/misc/RepairBacpac.Qualifier.json\\nQualifier means, that we can remove complex elements, based on some basic logic. E.g.\\n{\\r\\n\\\"Search\\\": \\\"*\\u003cElement Type=\\\\\\\"SqlRoleMembership\\\\\\\"\\u003e*\\\",\\r\\n\\\"Qualifier\\\": \\\"*\\u003cReferences Name=*ms_db_configwriter*\\\",\\r\\n\\\"End\\\": \\\"*\\u003c/Element\\u003e*\\\"\\r\\n}\\n\\\"*\\u003cElement Type=\\\\\\\"SqlRoleMembership\\\\\\\"\\u003e*\\\" can identify below, \\\"*\\u003cReferences Name=*ms_db_configwriter*\\\" qualifies that we are locating the correct one and together with \\\"*\\u003c/Element\\u003e*\\\" - we know when to \\r\\nstop.\\n\\u003cElement Type=\\\"SqlRoleMembership\\\"\\u003e\\r\\n\\u003cRelationship Name=\\\"Member\\\"\\u003e\\r\\n\\u003cEntry\\u003e\\r\\n\\u003cReferences Name=\\\"[ms_db_configwriter]\\\" /\\u003e\\r\\n\\u003c/Entry\\u003e\\r\\n\\u003c/Relationship\\u003e\\r\\n\\u003cRelationship Name=\\\"Role\\\"\\u003e\\r\\n\\u003cEntry\\u003e\\r\\n\\u003cReferences ExternalSource=\\\"BuiltIns\\\" Name=\\\"[db_ddladmin]\\\" /\\u003e\\r\\n\\u003c/Entry\\u003e\\r\\n\\u003c/Relationship\\u003e\\r\\n\\u003c/Element\\u003e\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$script:ModuleRoot\\\\internal\\\\misc\\\\RepairBacpac.Qualifier.json\\\"\"\n                       ],\n                       [\n                           \"PathRepairReplace\",\n                           \"Path to the json file, that contains all the instructions to be executed in the \\\"Replace\\\" section\\nThe default json file is part of the module, and can be located with the below command:\\r\\nexplorer.exe $(Join-Path -Path $(Split-Path -Path (Get-Module d365fo.tools -ListAvailable)[0].Path -Parent) -ChildPath \\\"internal\\\\misc\\\")\\r\\n- Look for the \\\"RepairBacpac.Replace.json\\\" file\\nOr you can see the latest version, online, inside the github repository: https://github.com/d365collaborative/d365fo.tools/tree/master/d365fo.tools/internal/misc/RepairBacpac.Replace.json\\nReplace means, that we can replace/remove strings, based on some basic logic. E.g.\\n{\\r\\n\\\"Search\\\": \\\"\\u003cProperty Name=\\\\\\\"AutoDrop\\\\\\\" Value=\\\\\\\"True\\\\\\\" /\\u003e\\\",\\r\\n\\\"Replace\\\": \\\"\\\"\\r\\n}\\n\\\"\\u003cProperty Name=\\\\\\\"AutoDrop\\\\\\\" Value=\\\\\\\"True\\\\\\\" /\\u003e\\\" can identify below, and \\\"\\\" is the value we want to replace with it.\\n\\u003cProperty Name=\\\"AutoDrop\\\" Value=\\\"True\\\" /\\u003e\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$script:ModuleRoot\\\\internal\\\\misc\\\\RepairBacpac.Replace.json\\\"\"\n                       ],\n                       [\n                           \"KeepFiles\",\n                           \"Instruct the cmdlet to keep the files from the repair process\\nThe files are very large, so only use this as a way to analyze why your model file didn\\u0027t end up in the desired state\\nUse it while you evolve/develop your instructions, but remove it from ANY full automation scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Instruct the cmdlet to overwrite the file specified in the OutputPath if it already exists\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Repair a bacpac model file\",\n        \"Name\":  \"Repair-D365BacpacModelFile\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eRepair-D365BacpacModelFile -Path C:\\\\Temp\\\\Base.xml -PathRepairSimple \\u0027\\u0027 -PathRepairQualifier \\u0027\\u0027 -PathRepairReplace \\u0027C:\\\\Temp\\\\RepairBacpac.Replace.Custom.json\\u0027\\nThis will only process the Replace section, as the other repair paths are empty - indicating to skip them.\\r\\nIt will load the instructions from the \\u0027C:\\\\Temp\\\\RepairBacpac.Replace.Custom.json\\u0027 file and run those in the Replace section.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eRepair-D365BacpacModelFile -Path C:\\\\Temp\\\\Base.xml -KeepFiles -Force\\nThis will process all repair sections.\\r\\nIt will keep the files in the temporary work directory, for the user to analyze the files further.\\r\\nIt will Force overwrite the output file, if it exists already.\",\n        \"Syntax\":  \"Repair-D365BacpacModelFile [-Path] \\u003cString\\u003e [[-OutputPath] \\u003cString\\u003e] [[-PathRepairSimple] \\u003cString\\u003e] [[-PathRepairQualifier] \\u003cString\\u003e] [[-PathRepairReplace] \\u003cString\\u003e] [-KeepFiles] [-Force] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Restart-D365Environment\",\n        \"Description\":  \"Restart the different services in a Dynamics 365 Finance \\u0026 Operations environment\",\n        \"Tags\":  [\n                     \"Environment\",\n                     \"Service\",\n                     \"Services\",\n                     \"Aos\",\n                     \"Batch\",\n                     \"Servicing\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"ComputerName\",\n                           \"An array of computers that you want to work against\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"@($env:computername)\"\n                       ],\n                       [\n                           \"All\",\n                           \"Instructs the cmdlet work against all relevant services\\nIncludes:\\r\\nAos\\r\\nBatch\\r\\nFinancial Reporter\\r\\nDMF\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"True\"\n                       ],\n                       [\n                           \"Aos\",\n                           \"Instructs the cmdlet to work against the AOS (IIS) service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Batch\",\n                           \"Instructs the cmdlet to work against the Batch service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"FinancialReporter\",\n                           \"Instructs the cmdlet to work against the Financial Reporter (Management Reporter 2012)\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"DMF\",\n                           \"Instructs the cmdlet to work against the DMF service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Kill\",\n                           \"Instructs the cmdlet to kill the service(s) that you want to restart\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Restart the different services\",\n        \"Name\":  \"Restart-D365Environment\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eRestart-D365Environment -All\\nThis will stop all services and then start all services again.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eRestart-D365Environment -All -ShowOriginalProgress\\nThis will stop all services and then start all services again.\\r\\nThe progress of Stopping the different services will be written to the console / host.\\r\\nThe progress of Starting the different services will be written to the console / host.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eRestart-D365Environment -ComputerName \\\"TEST-SB-AOS1\\\",\\\"TEST-SB-AOS2\\\",\\\"TEST-SB-BI1\\\" -All\\nThis will work against the machines: \\\"TEST-SB-AOS1\\\",\\\"TEST-SB-AOS2\\\",\\\"TEST-SB-BI1\\\".\\r\\nThis will stop all services and then start all services again.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eRestart-D365Environment -Aos -Batch\\nThis will stop the AOS and Batch services and then start the AOS and Batch services again.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eRestart-D365Environment -FinancialReporter -DMF\\nThis will stop the FinancialReporter and DMF services and then start the FinancialReporter and DMF services again.\\n-------------------------- EXAMPLE 6 --------------------------\\nPS C:\\\\\\u003eRestart-D365Environment -All -Kill\\nThis will stop all services and then start all services again.\\r\\nIt will use the Kill parameter to make sure that the services is stopped.\",\n        \"Syntax\":  \"Restart-D365Environment [[-ComputerName] \\u003cString[]\\u003e] [[-All]] [-Kill] [-ShowOriginalProgress] [\\u003cCommonParameters\\u003e]\\nRestart-D365Environment [[-ComputerName] \\u003cString[]\\u003e] [[-Aos]] [[-Batch]] [[-FinancialReporter]] [[-DMF]] [-Kill] [-ShowOriginalProgress] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Restore-D365DevConfig\",\n        \"Description\":  \"Will restore the DynamicsDevConfig.xml file located in the PackagesLocalDirectory\\\\Bin folder\",\n        \"Tags\":  [\n                     \"Web Server\",\n                     \"IIS\",\n                     \"IIS Express\",\n                     \"Development\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the folder where you the desired DynamicsDevConfig.xml file that you want restored is located\\nDefault is: \\\"C:\\\\Temp\\\\d365fo.tools\\\\DevConfigBackup\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path $Script:DefaultTempPath \\\"DevConfigBackup\\\")\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Instructs the cmdlet to overwrite the destination file if it already exists\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Sander Holvoet (@smholvoet)\",\n        \"Synopsis\":  \"Restore the DynamicsDevConfig.xml file\",\n        \"Name\":  \"Restore-D365DevConfig\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eRestore-D365DevConfig -Force\\nWill restore the DynamicsDevConfig.xml file, and overwrite the current DynamicsDevConfig.xml file in the PackagesLocalDirectory\\\\Bin folder.\\r\\nIt will use the default path \\\"C:\\\\Temp\\\\d365fo.tools\\\\DevConfigBackup\\\" as the source directory.\\r\\nIt will overwrite the current DynamicsDevConfig.xml file.\\nA result set example:\\nFilename              LastModified         File\\r\\n--------              ------------         ----\\r\\nDynamicsDevConfig.xml 6/29/2021 7:31:04 PM K:\\\\AosService\\\\PackagesLocalDirectory\\\\Bin\\\\DynamicsDevConfig.xml\",\n        \"Syntax\":  \"Restore-D365DevConfig [[-Path] \\u003cString\\u003e] [-Force] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Restore-D365WebConfig\",\n        \"Description\":  \"Will restore the web.config file located back into the AOS / IIS folder\",\n        \"Tags\":  [\n                     \"DEV\",\n                     \"Tier2\",\n                     \"DB\",\n                     \"Database\",\n                     \"Debug\",\n                     \"JIT\",\n                     \"LCS\",\n                     \"Azure DB\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the folder where you the desired web.config file that you want restored is located\\nDefault is: \\\"C:\\\\Temp\\\\d365fo.tools\\\\WebConfigBackup\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path $Script:DefaultTempPath \\\"WebConfigBackup\\\")\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Instructs the cmdlet to overwrite the destination file if it already exists\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Restore the web.config file\",\n        \"Name\":  \"Restore-D365WebConfig\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eRestore-D365WebConfig -Force\\nWill restore the web.config file, and overwrite the current web.config file in the AOS / IIS folder.\\r\\nIt will use the default path \\\"C:\\\\Temp\\\\d365fo.tools\\\\WebConfigBackup\\\" as the source directory.\\r\\nIt will overwrite the current web.config file.\\nA result set example:\\nFilename   LastModified         File\\r\\n--------   ------------         ----\\r\\nweb.config 6/29/2021 7:31:04 PM K:\\\\AosService\\\\WebRoot\\\\web.config\",\n        \"Syntax\":  \"Restore-D365WebConfig [[-Path] \\u003cString\\u003e] [-Force] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Send-D365BroadcastMessage\",\n        \"Description\":  \"Utilize the same messaging framework available from LCS and send a broadcast message to all online users in the environment\",\n        \"Tags\":  [\n                     \"Servicing\",\n                     \"Message\",\n                     \"Users\",\n                     \"Environment\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Tenant\",\n                           \"Azure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to send a message to\",\n                           \"$AADGuid\",\n                           false,\n                           \"false\",\n                           \"$Script:BroadcastTenant\"\n                       ],\n                       [\n                           \"URL\",\n                           \"URL / URI for the D365FO environment you want to send a message to\",\n                           \"URI\",\n                           false,\n                           \"false\",\n                           \"$Script:BroadcastUrl\"\n                       ],\n                       [\n                           \"ClientId\",\n                           \"The ClientId obtained from the Azure Portal when you created a Registered Application\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:BroadcastClientId\"\n                       ],\n                       [\n                           \"ClientSecret\",\n                           \"The ClientSecret obtained from the Azure Portal when you created a Registered Application\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:BroadcastClientSecret\"\n                       ],\n                       [\n                           \"TimeZone\",\n                           \"Id of the Time Zone your environment is running in\\nYou might experience that the local VM running the D365FO is running another Time Zone than the computer you are running this cmdlet from\\nAll available .NET Time Zones can be traversed with tab for this parameter\\nThe default value is \\\"UTC\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:BroadcastTimeZone\"\n                       ],\n                       [\n                           \"StartTime\",\n                           \"The time and date you want the message to be displayed for the users\\nDefault value is NOW\\nThe specified StartTime will always be based on local Time Zone. If you specify a different Time Zone than the local computer is running, the start and end time will be calculated based on your \\r\\nselection.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"(Get-Date)\"\n                       ],\n                       [\n                           \"EndingInMinutes\",\n                           \"Specify how many minutes into the future you want this message / maintenance window to last\\nDefault value is 60 minutes\\nThe specified StartTime will always be based on local Time Zone. If you specify a different Time Zone than the local computer is running, the start and end time will be calculated based on your \\r\\nselection.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:BroadcastEndingInMinutes\"\n                       ],\n                       [\n                           \"OnPremise\",\n                           \"Specify if environnement is an D365 OnPremise\\nDefault value is \\\"Not set\\\" (= Cloud Environnement)\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:BroadcastOnPremise\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Send broadcast message to online users in D365FO\",\n        \"Name\":  \"Send-D365BroadcastMessage\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSend-D365BroadcastMessage\\nThis will send a message to all active users that are working on default D365FO environment.\\nSee the RELATED LINKS section for the supporting cmdlets needed to store a default configuration.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eSend-D365BroadcastMessage -Tenant \\\"e674da86-7ee5-40a7-b777-1111111111111\\\" -URL \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\" -ClientId \\\"dea8d7a9-1602-4429-b138-111111111111\\\" \\r\\n-ClientSecret \\\"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\\\"\\nThis will send a message to all active users that are working on the D365FO environment located at \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\".\\r\\nIt will authenticate against the Azure Active Directory with the \\\"e674da86-7ee5-40a7-b777-1111111111111\\\" guid.\\r\\nIt will use the ClientId \\\"dea8d7a9-1602-4429-b138-111111111111\\\" and ClientSecret \\\"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\\\" go get access to the environment.\\r\\nIt will use the default value \\\"UTC\\\" Time Zone for converting the different time and dates.\\r\\nIt will use the default start time which is NOW.\\r\\nIt will use the default end time which is 60 minutes.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eSend-D365BroadcastMessage -OnPremise -Tenant \\\"https://adfs.local/adfs\\\" -URL \\\"https://ax-sandbox.d365fo.local\\\" -ClientId \\\"dea8d7a9-1602-4429-b138-111111111111\\\" -ClientSecret \\r\\n\\\"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\\\"\\nThis will send a message to all active users that are working on the D365FO OnPremise environment located at \\\"https://ax-sandbox.d365fo.local\\\".\\r\\nIt will authenticate against Local ADFS with the \\\"https://adfs.local/adfs\\\" path\\r\\nIt will use the ClientId \\\"dea8d7a9-1602-4429-b138-111111111111\\\" and ClientSecret \\\"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\\\" go get access to the environment.\\r\\nIt will use the default value \\\"UTC\\\" Time Zone for converting the different time and dates.\\r\\nIt will use the default start time which is NOW.\\r\\nIt will use the default end time which is 60 minutes.\",\n        \"Syntax\":  \"Send-D365BroadcastMessage [[-Tenant] \\u003cString\\u003e] [[-URL] \\u003cString\\u003e] [[-ClientId] \\u003cString\\u003e] [[-ClientSecret] \\u003cString\\u003e] [[-TimeZone] \\u003cString\\u003e] [[-StartTime] \\u003cDateTime\\u003e] [[-EndingInMinutes] \\u003cInt32\\u003e] [[-OnPremise]] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365ActiveAzureStorageConfig\",\n        \"Description\":  \"Updates the current active Azure Storage Account configuration with a new one\",\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"The name the Azure Storage Account configuration you want to load into the active Azure Storage Account configuration\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ConfigStorageLocation\",\n                           \"Parameter used to instruct where to store the configuration objects\\nThe default value is \\\"User\\\" and this will store all configuration for the active user\\nValid options are:\\r\\n\\\"User\\\"\\r\\n\\\"System\\\"\\n\\\"System\\\" will store the configuration so all users can access the configuration objects\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"User\"\n                       ],\n                       [\n                           \"Temporary\",\n                           \"Instruct the cmdlet to only temporarily override the persisted settings in the configuration storage\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Set the active Azure Storage Account configuration\",\n        \"Name\":  \"Set-D365ActiveAzureStorageConfig\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365ActiveAzureStorageConfig -Name \\\"UAT-Exports\\\"\\nThis will import the \\\"UAT-Exports\\\" set from the Azure Storage Account configurations.\\r\\nIt will update the active Azure Storage Account configuration.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eSet-D365ActiveAzureStorageConfig -Name \\\"UAT-Exports\\\" -ConfigStorageLocation \\\"System\\\"\\nThis will import the \\\"UAT-Exports\\\" set from the Azure Storage Account configurations.\\r\\nIt will update the active Azure Storage Account configuration.\\r\\nThe data will be stored in the system wide configuration storage, which makes it accessible from all users.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eSet-D365ActiveAzureStorageConfig -Name \\\"UAT-Exports\\\" -Temporary\\nThis will import the \\\"UAT-Exports\\\" set from the Azure Storage Account configurations.\\r\\nIt will update the active Azure Storage Account configuration.\\r\\nThe update will only last for the rest of this PowerShell console session.\",\n        \"Syntax\":  \"Set-D365ActiveAzureStorageConfig [[-Name] \\u003cString\\u003e] [[-ConfigStorageLocation] \\u003cString\\u003e] [-Temporary] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365ActiveBroadcastMessageConfig\",\n        \"Description\":  \"Updates the current active broadcast message configuration with a new one\",\n        \"Tags\":  [\n                     \"Servicing\",\n                     \"Message\",\n                     \"Users\",\n                     \"Environment\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"ClientId\",\n                     \"ClientSecret\",\n                     \"OnPremise\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"Name of the broadcast message configuration you want to load into the active broadcast message configuration\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Temporary\",\n                           \"Instruct the cmdlet to only temporarily override the persisted settings in the configuration store\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Set the active broadcast message configuration\",\n        \"Name\":  \"Set-D365ActiveBroadcastMessageConfig\",\n        \"Links\":  [\n                      null,\n                      null,\n                      null,\n                      null,\n                      null,\n                      null\n                  ],\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365ActiveBroadcastMessageConfig -Name \\\"UAT\\\"\\nThis will set the broadcast message configuration named \\\"UAT\\\" as the active configuration.\",\n        \"Syntax\":  \"Set-D365ActiveBroadcastMessageConfig [-Name] \\u003cString\\u003e [-Temporary] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365Admin\",\n        \"Description\":  \"Cmdlet using the AdminProvisioning tool from D365FO\",\n        \"Params\":  [\n                       [\n                           \"AdminSignInName\",\n                           \"Email for the Admin\",\n                           \"Email\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Rasmus Andersen (@ITRasmus)\",\n        \"Synopsis\":  \"Powershell implementation of the AdminProvisioning tool\",\n        \"Name\":  \"Set-D365Admin\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365Admin \\\"claire@contoso.com\\\"\\nThis will provision claire@contoso.com as administrator for the environment\",\n        \"Syntax\":  \"Set-D365Admin [-AdminSignInName] \\u003cString\\u003e [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365AzCopyPath\",\n        \"Description\":  \"Update the path where the module will be looking for the AzCopy.exe executable\",\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the AzCopy.exe\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Set the path for AzCopy.exe\",\n        \"Name\":  \"Set-D365AzCopyPath\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eInvoke-D365InstallAzCopy -Path \\\"C:\\\\temp\\\\d365fo.tools\\\\AzCopy\\\\AzCopy.exe\\\"\\nThis will update the path for the AzCopy.exe in the modules configuration\",\n        \"Syntax\":  \"Set-D365AzCopyPath [-Path] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365ClickOnceTrustPrompt\",\n        \"Description\":  \"Creates the needed registry keys and values for ClickOnce to work on the machine\",\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Set the ClickOnce needed configuration\",\n        \"Name\":  \"Set-D365ClickOnceTrustPrompt\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365ClickOnceTrustPrompt\\nThis will create / or update the current ClickOnce configuration.\",\n        \"Syntax\":  \"Set-D365ClickOnceTrustPrompt [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365DefaultModelForNewProjects\",\n        \"Description\":  \"Set the registered default model that is used across all new projects that are created inside Visual Studio when working with D365FO project types\\n\\nIt will backup the current \\\"DynamicsDevConfig.xml\\\" file, for you to revert the changes if anything should go wrong\",\n        \"Params\":  [\n                       [\n                           \"Module\",\n                           \"The name of the module / model that you want to be the default model for all new projects used inside Visual Studio when working with D365FO project types\",\n                           \"Model\",\n                           true,\n                           \"true (ByValue, ByPropertyName)\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Set the default model used creating new projects in Visual Studio\",\n        \"Name\":  \"Set-D365DefaultModelForNewProjects\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365DefaultModelForNewProjects -Model \\\"FleetManagement\\\"\\nThis will update the current default module registered in the \\\"DynamicsDevConfig.xml\\\" file.\\r\\nThis file is located in Documents\\\\Visual Studio Dynamics 365\\\\ or in Documents\\\\Visual Studio 2015\\\\Settings\\\\ depending on the version.\\r\\nIt will backup the current \\\"DynamicsDevConfig.xml\\\" file.\\r\\nIt will replace the value inside the \\\"DefaultModelForNewProjects\\\" tag.\",\n        \"Syntax\":  \"Set-D365DefaultModelForNewProjects [-Module] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365FavoriteBookmark\",\n        \"Description\":  \"Enable the favorite bar in Edge \\u0026 Chrome and put in the URL as a favorite/bookmark\",\n        \"Params\":  [\n                       [\n                           \"URL\",\n                           \"The URL of the shortcut you want to add to the favorite bar\",\n                           \"\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"D365FO\",\n                           \"Instruct the cmdlet that you want the populate the D365FO favorite entry based on the URL provided\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"AzureDevOps\",\n                           \"Instruct the cmdlet that you want the populate the AzureDevOps favorite entry based on the URL provided\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Enable the favorite bar and add an URL\",\n        \"Name\":  \"Set-D365FavoriteBookmark\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365FavoriteBookmark -Url \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\"\\nThis will add the \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\" to the favorite bar, enable the favorite bar and lock it.\\r\\nThis will be interpreted as the using the -D365FO parameter also, because that is the expected behavior.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eSet-D365FavoriteBookmark -Url \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\" -D365FO\\nThis will add the \\\"https://usnconeboxax1aos.cloud.onebox.dynamics.com\\\" to the favorite bar, enable the favorite bar and lock it.\\r\\nThe bookmark will be mapped as the one for the Dynamics 365 Finance \\u0026 Operations instance.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eSet-D365FavoriteBookmark -Url \\\"https://CUSTOMERNAME.visualstudio.com/\\\" -AzureDevOps\\nThis will add the \\\"https://CUSTOMERNAME.visualstudio.com/\\\" to the favorite bar, enable the favorite bar and lock it.\\r\\nThe bookmark will be mapped as the one for the Azure DevOps instance.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eGet-D365Url | Set-D365FavoriteBookmark\\nThis will get the URL from the environment and add that to the favorite bar, enable the favorite bar and lock it.\\r\\nThis will be interpreted as the using the -D365FO parameter also, because that is the expected behavior.\",\n        \"Syntax\":  \"Set-D365FavoriteBookmark [-URL \\u003cString\\u003e] [-D365FO] [\\u003cCommonParameters\\u003e]\\nSet-D365FavoriteBookmark [-URL \\u003cString\\u003e] [-AzureDevOps] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365FlightServiceCatalogId\",\n        \"Description\":  \"Set the FlightingServiceCatalogID element in the web.config file used by D365FO\",\n        \"Tags\":  [\n                     \"Flight\",\n                     \"Flighting\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"FlightServiceCatalogId\",\n                           \"Flighting catalog ID to be set\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"12719367\"\n                       ],\n                       [\n                           \"AosServiceWebRootPath\",\n                           \"Path to the root folder where to locate the web.config file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:AOSPath\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Frank Hüther(@FrankHuether))\",\n        \"Synopsis\":  \"Set the FlightingServiceCatalogID\",\n        \"Name\":  \"Set-D365FlightServiceCatalogId\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365FlightServiceCatalogId\\nThis will set the FlightingServiceCatalogID element the web.config to the default value \\\"12719367\\\".\",\n        \"Syntax\":  \"Set-D365FlightServiceCatalogId [[-FlightServiceCatalogId] \\u003cString\\u003e] [[-AosServiceWebRootPath] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365LcsApiConfig\",\n        \"Description\":  \"Set the LCS configuration details and save them into the configuration store\",\n        \"Tags\":  [\n                     \"Environment\",\n                     \"Url\",\n                     \"Config\",\n                     \"Configuration\",\n                     \"LCS\",\n                     \"Upload\",\n                     \"ClientId\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"ProjectId\",\n                           \"The project id for the Dynamics 365 for Finance \\u0026 Operations project inside LCS\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"0\"\n                       ],\n                       [\n                           \"ClientId\",\n                           \"The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"BearerToken\",\n                           \"The token you want to use when working against the LCS api\",\n                           \"AccessToken,access_token\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"ActiveTokenExpiresOn\",\n                           \"The point in time where the current bearer token will expire\\nThe time is measured in Unix Time, total seconds since 1970-01-01\",\n                           \"expires_on\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"0\"\n                       ],\n                       [\n                           \"RefreshToken\",\n                           \"The Refresh Token that you want to use for the authentication process\",\n                           \"refresh_token\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"LcsApiUri\",\n                           \"URI / URL to the LCS API you want to use\\nThe value depends on where your LCS project is located. There are multiple valid URI\\u0027s / URL\\u0027s\\nValid options:\\r\\n\\\"https://lcsapi.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.eu.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.fr.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.sa.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.uae.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.ch.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.no.lcs.dynamics.com\\\"\\r\\n\\\"https://lcsapi.lcs.dynamics.cn\\\"\\r\\n\\\"https://lcsapi.gov.lcs.microsoftdynamics.us\\\"\",\n                           \"resource\",\n                           false,\n                           \"true (ByPropertyName)\",\n                           \"https://lcsapi.lcs.dynamics.com\"\n                       ],\n                       [\n                           \"Temporary\",\n                           \"Instruct the cmdlet to only temporarily override the persisted settings in the configuration storage\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Set the LCS configuration details\",\n        \"Name\":  \"Set-D365LcsApiConfig\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365LcsApiConfig -ProjectId 123456789 -ClientId \\\"9b4f4503-b970-4ade-abc6-2c086e4c4929\\\" -BearerToken \\\"JldjfafLJdfjlfsalfd...\\\" -ActiveTokenExpiresOn 1556909205 -RefreshToken \\r\\n\\\"Tsdljfasfe2j32324\\\" -LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\"\\nThis will set the LCS API configuration.\\r\\nThe ProjectId 123456789 will be saved as the default ProjectId for all cmdlets that will interact with LCS, if they require a ProjectId.\\r\\nThe ClientId \\\"9b4f4503-b970-4ade-abc6-2c086e4c4929\\\" will be saved as the default ClientId for all cmdlets that will interact with LCS, if they require a ClientId.\\r\\nThe BearerToken \\\"JldjfafLJdfjlfsalfd...\\\" will be saved as the default BearerToken. Remember the BearerToken will expire, so you should fill in the ActiveTokenExpiresOn and RefreshToken parameters \\r\\nalso.\\r\\nThe ActiveTokenExpiresOn 1556909205 will be saved to assist the module in determine whether the BearerToken is still valid or not.\\r\\nThe RefreshToken \\\"Tsdljfasfe2j32324\\\" will be saved as the default RefreshToken for all cmdlets that will interact with tokens.\\r\\nThe LcsApiUri \\\"https://lcsapi.lcs.dynamics.com\\\" will be saved as the default LCS HTTP endpoint for all cmdlets that will interact with LCS.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eGet-D365LcsApiToken -Username \\\"serviceaccount@domain.com\\\" -Password \\\"TopSecretPassword\\\" | Set-D365LcsApiConfig\\nThis will obtain a valid OAuth 2.0 access token from Azure Active Directory and save the needed details.\\r\\nThe Username \\\"serviceaccount@domain.com\\\" and Password \\\"TopSecretPassword\\\" is used in the OAuth 2.0 Grant Flow, to approved that the application should impersonate like \\\"serviceaccount@domain.com\\\".\\r\\nThe output object received from Get-D365LcsApiToken is piped directly to Set-D365LcsApiConfig.\\r\\nSet-D365LcsApiConfig will save the access_token(BearerToken), refresh_token(RefreshToken) and expires_on(ActiveTokenExpiresOn).\\nThese values will then be available as default values for all LCS cmdlets across the module.\\nYou can validate the current default values by calling Get-D365LcsApiConfig.\",\n        \"Syntax\":  \"Set-D365LcsApiConfig [[-ProjectId] \\u003cInt32\\u003e] [[-ClientId] \\u003cString\\u003e] [[-BearerToken] \\u003cString\\u003e] [[-ActiveTokenExpiresOn] \\u003cInt64\\u003e] [[-RefreshToken] \\u003cString\\u003e] [[-LcsApiUri] \\u003cString\\u003e] [-Temporary] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365NugetPath\",\n        \"Description\":  \"Update the path where the module will be looking for the nuget.exe executable\",\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the nuget.exe\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Set the path for nuget.exe\",\n        \"Name\":  \"Set-D365NugetPath\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365NugetPath -Path \\\"C:\\\\temp\\\\d365fo.tools\\\\nuget\\\\nuget.exe\\\"\\nThis will update the path for the nuget.exe in the modules configuration\",\n        \"Syntax\":  \"Set-D365NugetPath [-Path] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365OfflineAuthenticationAdminEmail\",\n        \"Description\":  \"Sets the registered offline administrator in the \\\"DynamicsDevConfig.xml\\\" file located in the default Package Directory\",\n        \"Params\":  [\n                       [\n                           \"Email\",\n                           \"The desired email address of the to be offline administrator\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Sets the offline administrator e-mail\",\n        \"Name\":  \"Set-D365OfflineAuthenticationAdminEmail\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365OfflineAuthenticationAdminEmail -Email \\\"admin@contoso.com\\\"\\nWill update the Offline Administrator E-mail address in the DynamicsDevConfig.xml file with \\\"admin@contoso.com\\\"\",\n        \"Syntax\":  \"Set-D365OfflineAuthenticationAdminEmail [-Email] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365RsatConfiguration\",\n        \"Description\":  \"Update different RSAT configuration values while using the tool\",\n        \"Tags\":  [\n                     \"RSAT\",\n                     \"Testing\",\n                     \"Regression Suite Automation Test\",\n                     \"Regression\",\n                     \"Test\",\n                     \"Automation\",\n                     \"Configuration\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"LogGenerationEnabled\",\n                           \"Will set the LogGeneration property\\n$true will make RSAT start generating logs\\r\\n$false will stop RSAT from generating logs\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"VerboseSnapshotsEnabled\",\n                           \"Will set the VerboseSnapshotsEnabled property\\n$true will make RSAT start generating snapshots and store related details\\r\\n$false will stop RSAT from generating snapshots and store related details\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"AddOperatorFieldsToExcelValidationEnabled\",\n                           \"Will set the AddOperatorFieldsToExcelValidation property\\n$true will make RSAT start adding the operation options in the excel parameter file\\r\\n$false will stop RSAT from adding the operation options in the excel parameter file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"RSATConfigFilename\",\n                           \"Specifies the file name of the RSAT configuration file. Default is \\u0027Microsoft.Dynamics.RegressionSuite.WpfApp.exe.config\\u0027\\r\\nIf you are using an older version of RSAT, you might need to change this to \\u0027Microsoft.Dynamics.RegressionSuite.WindowsApp.exe.config\\u0027\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"Microsoft.Dynamics.RegressionSuite.WpfApp.exe.config\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Set different RSAT configuration values\",\n        \"Name\":  \"Set-D365RsatConfiguration\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365RsatConfiguration -LogGenerationEnabled $true\\nThis will enable the log generation logic of RSAT.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eSet-D365RsatConfiguration -VerboseSnapshotsEnabled $true\\nThis will enable the snapshot generation logic of RSAT.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eSet-D365RsatConfiguration -AddOperatorFieldsToExcelValidationEnabled $true\\nThis will enable the operator generation logic of RSAT.\",\n        \"Syntax\":  \"Set-D365RsatConfiguration [[-LogGenerationEnabled] \\u003cBoolean\\u003e] [[-VerboseSnapshotsEnabled] \\u003cBoolean\\u003e] [[-AddOperatorFieldsToExcelValidationEnabled] \\u003cBoolean\\u003e] [[-RSATConfigFilename] \\u003cObject\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365RsatTier2Crypto\",\n        \"Description\":  \"Set the needed registry settings for when you are running RSAT against a Tier2+ environment\",\n        \"Tags\":  [\n                     \"RSAT\",\n                     \"Testing\",\n                     \"Regression Suite Automation Test\",\n                     \"Regression\",\n                     \"Test\",\n                     \"Automation\",\n                     \"Configuration\"\n                 ],\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Set the needed configuration to work on Tier2+ environments\",\n        \"Name\":  \"Set-D365RsatTier2Crypto\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365RsatTier2Crypto\\nThis will configure the registry to support RSAT against a Tier2+ environment.\",\n        \"Syntax\":  \"Set-D365RsatTier2Crypto [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365SDPCleanUp\",\n        \"Description\":  \"Sets the configured retention period before updates are deleted\",\n        \"Params\":  [\n                       [\n                           \"NumberOfDays\",\n                           \"Number of days that deployable software packages should remain on the server\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"30\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Set the cleanup retention period\",\n        \"Name\":  \"Set-D365SDPCleanUp\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365SDPCleanUp -NumberOfDays 10\\nThis will set the retention period to 10 days inside the the registry\\nThe cmdlet REQUIRES elevated permissions to run, otherwise it will fail\",\n        \"Syntax\":  \"Set-D365SDPCleanUp [[-NumberOfDays] \\u003cInt32\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365SqlPackagePath\",\n        \"Description\":  \"Update the path where the module will be looking for the SqlPackage.exe executable\",\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the SqlPackage.exe\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Set the path for SqlPackage.exe\",\n        \"Name\":  \"Set-D365SqlPackagePath\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365SqlPackagePath -Path \\\"C:\\\\Program Files\\\\Microsoft SQL Server\\\\150\\\\DAC\\\\bin\\\\SqlPackage.exe\\\"\\nThis will update the path for the SqlPackage.exe in the modules configuration\",\n        \"Syntax\":  \"Set-D365SqlPackagePath [-Path] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365StartPage\",\n        \"Description\":  \"Function for setting the start page in internet explorer\",\n        \"Params\":  [\n                       [\n                           \"Name\",\n                           \"Name of the D365 Instance\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Url\",\n                           \"URL of the D365 for Finance \\u0026 Operations instance that you want to have as your start page\",\n                           \"\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Rasmus Andersen (@ITRasmus)\",\n        \"Synopsis\":  \"Sets the start page in internet explorer\",\n        \"Name\":  \"Set-D365StartPage\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365StartPage -Name \\u0027Demo1\\u0027\\nThis will update the start page for the current user to \\\"https://Demo1.cloud.onebox.dynamics.com\\\"\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eSet-D365StartPage -URL \\\"https://uat.sandbox.operations.dynamics.com\\\"\\nThis will update the start page for the current user to \\\"https://uat.sandbox.operations.dynamics.com\\\"\",\n        \"Syntax\":  \"Set-D365StartPage [-Name] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\\nSet-D365StartPage [-Url] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365SysAdmin\",\n        \"Description\":  \"Set a user to sysadmin inside the SQL Server\",\n        \"Params\":  [\n                       [\n                           \"User\",\n                           \"The user that you want to make sysadmin\\nMost be well formatted server\\\\user or domain\\\\user.\\nDefault value is: machinename\\\\administrator\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$env:computername\\\\administrator\\\"\"\n                       ],\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@splaxi)\",\n        \"Synopsis\":  \"Set a user to sysadmin\",\n        \"Name\":  \"Set-D365SysAdmin\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365SysAdmin\\nThis will configure the local administrator on the machine as a SYSADMIN inside SQL Server\\nFor this to run you need to be running it from a elevated console\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eSet-D365SysAdmin -SqlPwd Test123\\nThis will configure the local administrator on the machine as a SYSADMIN inside SQL Server.\\r\\nIt will logon as the default SqlUser but use the provided SqlPwd.\\nThis can be run from a non-elevated console\",\n        \"Syntax\":  \"Set-D365SysAdmin [[-User] \\u003cString\\u003e] [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365TraceParserFileSize\",\n        \"Description\":  \"Change the maximum file size that the TraceParser generates\",\n        \"Params\":  [\n                       [\n                           \"FileSizeInMB\",\n                           \"The maximum size that you want to allow the TraceParser file to grow to\\nOriginal value inside the configuration is 1024 (MB)\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Path\",\n                           \"The path to the TraceParser.config file that you want to edit\\nThe default path is: \\\"\\\\AosService\\\\Webroot\\\\Services\\\\TraceParserService\\\\TraceParserService.config\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"(Join-Path $Script:AOSPath \\\"Services\\\\TraceParserService\\\\TraceParserService.config\\\")\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Configue a new maximum file size for the TraceParser\",\n        \"Name\":  \"Set-D365TraceParserFileSize\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365TraceParserFileSize -FileSizeInMB 2048\\nThis will configure the maximum TraceParser file to 2048 MB.\",\n        \"Syntax\":  \"Set-D365TraceParserFileSize [-FileSizeInMB] \\u003cString\\u003e [[-Path] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365WebConfigDatabase\",\n        \"Description\":  \"Overwrite the current database connection details directly in the web.config file\\n\\nUsed when you want to connect a DEV box directly to a Tier2 database, and want to debug something that requires better data than usual\",\n        \"Tags\":  [\n                     \"DEV\",\n                     \"Tier2\",\n                     \"DB\",\n                     \"Database\",\n                     \"Debug\",\n                     \"JIT\",\n                     \"LCS\",\n                     \"Azure DB\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nObtain when you request JIT (Just-in-Time) access through the LCS portal\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\\nObtain when you request JIT (Just-in-Time) access through the LCS portal\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\\nObtain when you request JIT (Just-in-Time) access through the LCS portal\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\\nObtain when you request JIT (Just-in-Time) access through the LCS portal\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Path\",\n                           \"Path to the web.config file that you want to update with new SQL connection details\\nDefault is: \\\"K:\\\\AosService\\\\WebRoot\\\\web.config\\\" or what else drive that is recognized by the D365FO components as the service drive\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$(Join-Path -Path $Script:AOSPath -ChildPath $Script:WebConfig)\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Set the database connection details\",\n        \"Name\":  \"Set-D365WebConfigDatabase\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365WebConfigDatabase -DatabaseServer TestServer.database.windows.net -DatabaseName AxDB -SqlUser User123 -SqlPwd \\\"Password123\\\"\\nWill overwrite Server, Database, Username and Password directly in the web.config file.\\r\\nIt will save all details unencrypted.\",\n        \"Syntax\":  \"Set-D365WebConfigDatabase [-DatabaseServer] \\u003cString\\u003e [-DatabaseName] \\u003cString\\u003e [-SqlUser] \\u003cString\\u003e [-SqlPwd] \\u003cString\\u003e [[-Path] \\u003cObject\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365WebServerType\",\n        \"Description\":  \"Set the web server which will be used to run D365FO: Either IIS or IIS Express.\\nNewly deployed development machines will have this set to IIS Express by default.\\n\\nIt will backup the current \\\"DynamicsDevConfig.xml\\\" file, for you to revert the changes if anything should go wrong.\\n\\nIt will look for the file located in the default Package Directory.\",\n        \"Params\":  [\n                       [\n                           \"RuntimeHostType\",\n                           \"The type of web server you want to use.\\nValid options are:\\r\\n\\\"IIS\\\"\\r\\n\\\"IISExpress\\\"\",\n                           \"\",\n                           true,\n                           \"true (ByValue, ByPropertyName)\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Sander Holvoet (@smholvoet)\",\n        \"Synopsis\":  \"Set the web server type to be used to run the D365FO instance\",\n        \"Name\":  \"Set-D365WebServerType\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365WebServerType -RuntimeHostType \\\"IIS\\\"\\nThis will update the current web server type registered in the \\\"DynamicsDevConfig.xml\\\" file.\\r\\nThis file is located \\\"K:\\\\AosService\\\\PackagesLocalDirectory\\\\bin\\\".\\r\\nIt will backup the current \\\"DynamicsDevConfig.xml\\\" file.\\r\\nIt will replace the value inside the \\\"RuntimeHostType\\\" tag.\",\n        \"Syntax\":  \"Set-D365WebServerType [-RuntimeHostType] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Set-D365WorkstationMode\",\n        \"Description\":  \"Set the Workstation mode to enabled or not\\n\\nIt is used to enable the tool to run on a personal machine and still be able to call Invoke-D365TableBrowser and Invoke-D365SysRunnerClass\",\n        \"Params\":  [\n                       [\n                           \"Enabled\",\n                           \"$True enables the workstation mode while $false deactivated the workstation mode\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Set the Workstation mode\",\n        \"Name\":  \"Set-D365WorkstationMode\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSet-D365WorkstationMode -Enabled $true\\nThis will enable the Workstation mode.\\r\\nYou will have to restart the powershell session when you switch around.\",\n        \"Syntax\":  \"Set-D365WorkstationMode [-Enabled] \\u003cBoolean\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Start-D365Environment\",\n        \"Description\":  \"Can start all relevant services that is running in a D365FO environment\",\n        \"Params\":  [\n                       [\n                           \"ComputerName\",\n                           \"An array of computers that you want to start services on.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"@($env:computername)\"\n                       ],\n                       [\n                           \"All\",\n                           \"Set when you want to start all relevant services\\nIncludes:\\r\\nAos\\r\\nBatch\\r\\nFinancial Reporter\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"True\"\n                       ],\n                       [\n                           \"Aos\",\n                           \"Start the Aos (iis) service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Batch\",\n                           \"Start the batch service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"FinancialReporter\",\n                           \"Start the financial reporter (Management Reporter 2012) service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"DMF\",\n                           \"Start the Data Management Framework service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OnlyStartTypeAutomatic\",\n                           \"Instruct the cmdlet to filter out services that are set to manual start or disabled\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Cmdlet to start the different services in a Dynamics 365 Finance \\u0026 Operations environment\",\n        \"Name\":  \"Start-D365Environment\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eStart-D365Environment\\nThis will run the cmdlet with the default parameters.\\r\\nDefault is \\\"-All\\\".\\r\\nThis will start all D365FO services on the machine.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eStart-D365Environment -OnlyStartTypeAutomatic\\nThis will start all D365FO services on the machine that are configured for Automatic startup.\\r\\nIt will exclude all services that are either manual or disabled in their startup configuration.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eStart-D365Environment -ShowOriginalProgress\\nThis will run the cmdlet with the default parameters.\\r\\nDefault is \\\"-All\\\".\\r\\nThis will start all D365FO services on the machine.\\r\\nThe progress of starting the different services will be written to the console / host.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eStart-D365Environment -All\\nThis will start all D365FO services on the machine.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eStart-D365Environment -Aos -Batch\\nThis will start the Aos \\u0026 Batch D365FO services on the machine.\\n-------------------------- EXAMPLE 6 --------------------------\\nPS C:\\\\\\u003eStart-D365Environment -FinancialReporter -DMF\\nThis will start the FinancialReporter and DMF services on the machine.\",\n        \"Syntax\":  \"Start-D365Environment [[-ComputerName] \\u003cString[]\\u003e] [[-All]] [-OnlyStartTypeAutomatic] [-ShowOriginalProgress] [\\u003cCommonParameters\\u003e]\\nStart-D365Environment [[-ComputerName] \\u003cString[]\\u003e] [[-Aos]] [[-Batch]] [[-FinancialReporter]] [[-DMF]] [-OnlyStartTypeAutomatic] [-ShowOriginalProgress] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Start-D365EnvironmentV2\",\n        \"Description\":  \"Can start all relevant services that is running in a D365FO environment\",\n        \"Params\":  [\n                       [\n                           \"All\",\n                           \"Set when you want to start all relevant services\\nIncludes:\\r\\nAos\\r\\nBatch\\r\\nFinancial Reporter\\r\\nData Management Framework\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"True\"\n                       ],\n                       [\n                           \"Aos\",\n                           \"Start the Aos (iis) service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Batch\",\n                           \"Start the batch service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"FinancialReporter\",\n                           \"Start the financial reporter (Management Reporter 2012) service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"DMF\",\n                           \"Start the Data Management Framework service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"OnlyStartTypeAutomatic\",\n                           \"Instruct the cmdlet to filter out services that are set to manual start or disabled\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Vincent Verweij (@VincentVerweij)\",\n        \"Synopsis\":  \"Cmdlet to start the different services in a Dynamics 365 Finance \\u0026 Operations environment\",\n        \"Name\":  \"Start-D365EnvironmentV2\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eStart-D365EnvironmentV2\\nThis will run the cmdlet with the default parameters.\\r\\nDefault is \\\"-All\\\".\\r\\nThis will start all D365FO services on the machine.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eStart-D365EnvironmentV2 -OnlyStartTypeAutomatic\\nThis will start all D365FO services on the machine that are configured for Automatic startup.\\r\\nIt will exclude all services that are either manual or disabled in their startup configuration.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eStart-D365EnvironmentV2 -ShowOriginalProgress\\nThis will run the cmdlet with the default parameters.\\r\\nDefault is \\\"-All\\\".\\r\\nThis will start all D365FO services on the machine.\\r\\nThe progress of starting the different services will be written to the console / host.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eStart-D365EnvironmentV2 -All\\nThis will start all D365FO services on the machine.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eStart-D365EnvironmentV2 -Aos -Batch\\nThis will start the Aos \\u0026 Batch D365FO services on the machine.\\n-------------------------- EXAMPLE 6 --------------------------\\nPS C:\\\\\\u003eStart-D365EnvironmentV2 -FinancialReporter -DMF\\nThis will start the FinancialReporter and DMF services on the machine.\\n-------------------------- EXAMPLE 7 --------------------------\\nPS C:\\\\\\u003eEnable-D365Exception\\nPS C:\\\\\\u003e Start-D365EnvironmentV2\\nThis will run the cmdlet with the default parameters.\\r\\nDefault is \\\"-All\\\".\\r\\nThis will start all D365FO services on the machine.\\r\\nIf a service does not start, it will throw an exception.\",\n        \"Syntax\":  \"Start-D365EnvironmentV2 [[-All]] [-OnlyStartTypeAutomatic] [-ShowOriginalProgress] [\\u003cCommonParameters\\u003e]\\nStart-D365EnvironmentV2 [[-Aos]] [[-Batch]] [[-FinancialReporter]] [[-DMF]] [-OnlyStartTypeAutomatic] [-ShowOriginalProgress] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Start-D365EventTrace\",\n        \"Description\":  \"Start an Event Trace session with default values to help you getting started\",\n        \"Tags\":  [\n                     \"ETL\",\n                     \"EventTracing\",\n                     \"EventTrace\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"ProviderName\",\n                           \"Name of the provider(s) you want to have part of your trace\\nAccepts an array/list of provider names\",\n                           \"\",\n                           true,\n                           \"true (ByValue, ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"OutputPath\",\n                           \"Path to the output folder where you want to store the ETL file that will be generated\\nDefault path is \\\"C:\\\\Temp\\\\d365fo.tools\\\\EventTrace\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"(Join-Path -Path $Script:DefaultTempPath -ChildPath \\\"EventTrace\\\")\"\n                       ],\n                       [\n                           \"SessionName\",\n                           \"Name that you want the tracing session to have while running the trace\\nDefault value is \\\"d365fo.tools.trace\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"d365fo.tools.trace\"\n                       ],\n                       [\n                           \"FileName\",\n                           \"Name of the file that you want the trace to write its output to\\nDefault value is \\\"d365fo.tools.trace.etl\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"d365fo.tools.trace.etl\"\n                       ],\n                       [\n                           \"OutputFormat\",\n                           \"The desired output format of the ETL file being outputted from the tracing session\\nDefault value is \\\"bincirc\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"bincirc\"\n                       ],\n                       [\n                           \"MinBuffer\",\n                           \"The minimum buffer size in MB that you want the tracing session to work with\\nDefault value is 10240\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"10240\"\n                       ],\n                       [\n                           \"MaxBuffer\",\n                           \"The maximum buffer size in MB that you want the tracing session to work with\\nDefault value is 10240\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"10240\"\n                       ],\n                       [\n                           \"BufferSizeKB\",\n                           \"The buffer size in KB that you want the tracing session to work with\\nDefault value is 1024\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"1024\"\n                       ],\n                       [\n                           \"MaxLogFileSizeMB\",\n                           \"The maximum log file size in MB that you want the tracing session to work with\\nDefault value is 4096\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"4096\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Start an Event Trace session\",\n        \"Name\":  \"Start-D365EventTrace\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eStart-D365EventTrace -ProviderName \\\"Microsoft-Dynamics-AX-FormServer\\\",\\\"Microsoft-Dynamics-AX-XppRuntime\\\"\\nThis will start a new Event Tracing session with the binary circular output format.\\r\\nIt uses \\\"Microsoft-Dynamics-AX-FormServer\\\",\\\"Microsoft-Dynamics-AX-XppRuntime\\\" as the providernames.\\r\\nIt uses the default output folder \\\"C:\\\\Temp\\\\d365fo.tools\\\\EventTrace\\\".\\nIt will use the default values for the remaining parameters.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eStart-D365EventTrace -ProviderName \\\"Microsoft-Dynamics-AX-FormServer\\\",\\\"Microsoft-Dynamics-AX-XppRuntime\\\" -OutputFormat CSV\\nThis will start a new Event Tracing session with the comma separated output format.\\r\\nIt uses \\\"Microsoft-Dynamics-AX-FormServer\\\",\\\"Microsoft-Dynamics-AX-XppRuntime\\\" as the providernames.\\r\\nIt uses the default output folder \\\"C:\\\\Temp\\\\d365fo.tools\\\\EventTrace\\\".\\nIt will use the default values for the remaining parameters.\",\n        \"Syntax\":  \"Start-D365EventTrace [-ProviderName] \\u003cString[]\\u003e [[-OutputPath] \\u003cString\\u003e] [[-SessionName] \\u003cString\\u003e] [[-FileName] \\u003cString\\u003e] [[-OutputFormat] \\u003cString\\u003e] [[-MinBuffer] \\u003cInt32\\u003e] [[-MaxBuffer] \\u003cInt32\\u003e] [[-BufferSizeKB] \\u003cInt32\\u003e] [[-MaxLogFileSizeMB] \\u003cInt32\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Stop-D365Environment\",\n        \"Description\":  \"Can stop all relevant services that is running in a D365FO environment\",\n        \"Params\":  [\n                       [\n                           \"ComputerName\",\n                           \"An array of computers that you want to stop services on.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"@($env:computername)\"\n                       ],\n                       [\n                           \"All\",\n                           \"Set when you want to stop all relevant services\\nIncludes:\\r\\nAos\\r\\nBatch\\r\\nFinancial Reporter\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"True\"\n                       ],\n                       [\n                           \"Aos\",\n                           \"Stop the Aos (iis) service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Batch\",\n                           \"Stop the batch service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"FinancialReporter\",\n                           \"Start the financial reporter (Management Reporter 2012) service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"DMF\",\n                           \"Start the Data Management Framework service\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"Kill\",\n                           \"Instructs the cmdlet to kill the service(s) that you want to stop\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"ShowOriginalProgress\",\n                           \"Instruct the cmdlet to show the standard output in the console\\nDefault is $false which will silence the standard output\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Cmdlet to stop the different services in a Dynamics 365 Finance \\u0026 Operations environment\",\n        \"Name\":  \"Stop-D365Environment\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eStop-D365Environment\\nThis will run the cmdlet with the default parameters.\\r\\nDefault is \\\"-All\\\".\\r\\nThis will stop all D365FO services on the machine.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eStop-D365Environment -ShowOriginalProgress\\nThis will run the cmdlet with the default parameters.\\r\\nDefault is \\\"-All\\\".\\r\\nThis will Stop all D365FO services on the machine.\\r\\nThe progress of Stopping the different services will be written to the console / host.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eStop-D365Environment -All\\nThis will stop all D365FO services on the machine.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eStop-D365Environment -Aos -Batch\\nThis will stop the Aos \\u0026 Batch D365FO services on the machine.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eStop-D365Environment -FinancialReporter -DMF\\nThis will stop the FinancialReporter and DMF services on the machine.\\n-------------------------- EXAMPLE 6 --------------------------\\nPS C:\\\\\\u003eStop-D365Environment -All -Kill\\nThis will stop all D365FO services on the machine.\\r\\nIt will use the Kill parameter to make sure that the services is stopped.\",\n        \"Syntax\":  \"Stop-D365Environment [[-ComputerName] \\u003cString[]\\u003e] [[-All]] [[-Kill]] [[-ShowOriginalProgress]] [\\u003cCommonParameters\\u003e]\\nStop-D365Environment [[-ComputerName] \\u003cString[]\\u003e] [[-Aos]] [[-Batch]] [[-FinancialReporter]] [[-DMF]] [[-Kill]] [[-ShowOriginalProgress]] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Stop-D365EventTrace\",\n        \"Description\":  \"Stop an Event Trace session that you have started earlier with the d365fo.tools\",\n        \"Tags\":  [\n                     \"ETL\",\n                     \"EventTracing\",\n                     \"EventTrace\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"SessionName\",\n                           \"Name of the tracing session that you want to stop\\nDefault value is \\\"d365fo.tools.trace\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"d365fo.tools.trace\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Stop an Event Trace session\",\n        \"Name\":  \"Stop-D365EventTrace\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eStop-D365EventTrace\\nThis will stop an Event Trace session.\\r\\nIt will use the \\\"d365fo.tools.trace\\\" as the SessionName parameter.\",\n        \"Syntax\":  \"Stop-D365EventTrace [[-SessionName] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Switch-D365ActiveDatabase\",\n        \"Description\":  \"Switches the 2 databases. The Old wil be renamed _original\",\n        \"Params\":  [\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"DestinationDatabaseName\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"SourceDatabaseName\",\n                           \"The database that takes the DatabaseName\\u0027s place\",\n                           \"NewDatabaseName\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"DestinationSuffix\",\n                           \"The suffix that you want to append onto the database that is being switched out (DestinationDatabaseName / DatabaseName)\\nThe default value is \\\"_original\\\" to mimic the official guides from Microsoft\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"_original\"\n                       ],\n                       [\n                           \"EnableException\",\n                           \"This parameters disables user-friendly warnings and enables the throwing of exceptions\\r\\nThis is less user friendly, but allows catching exceptions in calling scripts\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Switches the 2 databases. The Old wil be renamed _original\",\n        \"Name\":  \"Switch-D365ActiveDatabase\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eSwitch-D365ActiveDatabase -SourceDatabaseName \\\"GoldenConfig\\\"\\nThis will switch the default database AXDB out and put \\\"GoldenConfig\\\" in its place instead.\\r\\nIt will use the default value for DestinationSuffix which is \\\"_original\\\".\\r\\nThe destination database \\\"AXDB\\\" will be renamed to \\\"AXDB_original\\\".\\r\\nThe GoldenConfig database will be renamed to \\\"AXDB\\\".\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eSwitch-D365ActiveDatabase -SourceDatabaseName \\\"AXDB_original\\\" -DestinationSuffix \\\"_reverted\\\"\\nThis will switch the default database AXDB out and put \\\"AXDB_original\\\" in its place instead.\\r\\nIt will use the \\\"_reverted\\\" value for DestinationSuffix parameter.\\r\\nThe destination database \\\"AXDB\\\" will be renamed to \\\"AXDB_reverted\\\".\\r\\nThe \\\"AXDB_original\\\" database will be renamed to \\\"AXDB\\\".\\nThis is used when you did a switch already and need to switch back to the original database.\\nThis example assumes that the used the first example to switch in the GoldenConfig database with default parameters.\",\n        \"Syntax\":  \"Switch-D365ActiveDatabase [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [-SourceDatabaseName] \\u003cString\\u003e [[-DestinationSuffix] \\u003cString\\u003e] [-EnableException] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Test-D365Command\",\n        \"Description\":  \"Analyze a function and it\\u0027s parameters\\n\\nThe cmdlet / function is capable of validating a string input with function name and parameters\",\n        \"Params\":  [\n                       [\n                           \"CommandText\",\n                           \"The string that you want to analyze\\nIf there is parameter value present, you have to use the opposite quote strategy to encapsulate the string correctly\\nE.g. for double quotes\\r\\n-CommandText \\u0027Import-D365Bacpac -ImportModeTier2 -SqlUser \\\"sqladmin\\\" -SqlPwd \\\"XyzXyz\\\" -BacpacFile2 \\\"C:\\\\temp\\\\uat.bacpac\\\"\\u0027\\nE.g. for single quotes\\r\\n-CommandText \\\"Import-D365Bacpac -ExportModeTier2 -SqlUser \\u0027sqladmin\\u0027 -SqlPwd \\u0027XyzXyz\\u0027 -BacpacFile2 \\u0027C:\\\\temp\\\\uat.bacpac\\u0027\\\"\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Mode\",\n                           \"The operation mode of the cmdlet / function\\nValid options are:\\r\\n- Validate\\r\\n- ShowParameters\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"SplatInput\",\n                           \"Pass in your hashtable that you use for your command execution and have it validated\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"ShowSplatStyleV1\",\n                           \"Include an hashtable splatting for all parameter sets in the output\\nThe example is built like this:\\r\\nPS C:\\\\\\u003e $params = @{}\\r\\nPS C:\\\\\\u003e $params.PropertyName = \\\"SAMPLEVALUE\\\"\\r\\nPS C:\\\\\\u003e Test-FakeCommand @params\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"ShowSplatStyleV2\",\n                           \"Include an hashtable splatting for all parameter sets in the output\\nThe example is built like this:\\r\\nPS C:\\\\\\u003e $params = @{\\r\\nPS C:\\\\\\u003e PropertyName = \\\"SAMPLEVALUE\\\"\\r\\nPS C:\\\\\\u003e }\\r\\nPS C:\\\\\\u003e Test-FakeCommand @params\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ],\n                       [\n                           \"IncludeHelp\",\n                           \"Switch to instruct the cmdlet / function to output a simple guide with the colors in it\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Validate or show parameter set details with colored output\",\n        \"Name\":  \"Test-D365Command\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eTest-D365Command -CommandText \\u0027Import-D365Bacpac -ImportModeTier2 -SqlUser \\\"sqladmin\\\" -SqlPwd \\\"XyzXyz\\\" -BacpacFile2 \\\"C:\\\\temp\\\\uat.bacpac\\\"\\u0027 -Mode \\\"Validate\\\" -IncludeHelp\\nThis will validate all the parameters that have been passed to the Import-D365Bacpac cmdlet.\\r\\nAll supplied parameters that matches a parameter will be marked with an asterisk.\\r\\nWill print the coloring help.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eTest-D365Command -CommandText \\u0027Import-D365Bacpac\\u0027 -Mode \\\"ShowParameters\\\" -IncludeHelp\\nThis will display all the parameter sets and their individual parameters.\\r\\nWill print the coloring help.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003e$params = @{}\\nPS C:\\\\\\u003e $params.DatabaseName = \\\"SAMPLEVALUE\\\"\\r\\nPS C:\\\\\\u003e Test-D365Command -CommandText \\u0027Import-D365Bacpac -ImportModeTier2\\u0027 -SplatInput $params -Mode \\\"Validate\\\"\\nThis builds a hashtable with a property names \\\"DatabaseName\\\".\\r\\nThe hashtable is passed to the cmdlet to be part of the validation.\",\n        \"Syntax\":  \"Test-D365Command [-CommandText] \\u003cString\\u003e [-Mode] \\u003cString\\u003e [-SplatInput \\u003cHashtable\\u003e] [-ShowSplatStyleV1] [-ShowSplatStyleV2] [-IncludeHelp] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Test-D365DataverseConnection\",\n        \"Description\":  \"Invokes the built-in http communication endpount, that validates the connection between the D365FO environment and dataverse\",\n        \"Params\":  [\n                       [\n                           \"BinDir\",\n                           \"The path to the bin directory for the environment\\nDefault path is the same as the aos service PackagesLocalDirectory\\\\bin\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\\\"$Script:BinDir\\\\bin\\\"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Synopsis\":  \"Test the dataverse connection\",\n        \"Name\":  \"Test-D365DataverseConnection\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eTest-D365DataverseConnection\\nThis will invoke the http communication component, that validates the basic settings between D365FO and Dataverse.\\r\\nIt will output the raw details from the call, to make it easier to troubleshoot the connectivity between D365FO and Dataverse.\",\n        \"Syntax\":  \"Test-D365DataverseConnection [[-BinDir] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Test-D365EntraIntegration\",\n        \"Description\":  \"Validates the configuration of the web.config file and the certificate for the environment\\n\\nIf any of the configuration is missing or in someway incorrect, it will prompt and stating corrective actions needed\",\n        \"Params\":  [\n\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Test the Entra Id integration\",\n        \"Name\":  \"Test-D365EntraIntegration\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eTest-D365EntraIntegration\\nThis will validate the settings inside the web.config file.\\r\\nIt will search for Aad.Realm, Infrastructure.S2SCertThumbprint, GraphApi.GraphAPIServicePrincipalCert\\r\\nIt will search for the certificate that matches the thumbprint.\\nA result set example:\\nEntraAppId                           Thumbprint                               Subject    Expiration\\r\\n----------                           ----------                               -------    ----------\\r\\ne068e004-8bec-48c3-a36f-2ab4982ee738 0768175DF3DFDEA3FA78925ADC1E588707649335 CN=CHEAuth 2/5/2026 8:09:28 AM\",\n        \"Syntax\":  \"Test-D365EntraIntegration [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Test-D365FlightServiceCatalogId\",\n        \"Description\":  \"Test if the FlightingServiceCatalogID element exists in the web.config file used by D365FO\",\n        \"Tags\":  [\n                     \"Flight\",\n                     \"Flighting\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"AosServiceWebRootPath\",\n                           \"Path to the root folder where to locate the web.config file\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:AOSPath\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi))\",\n        \"Synopsis\":  \"Test if the FlightingServiceCatalogID is present and filled out\",\n        \"Name\":  \"Test-D365FlightServiceCatalogId\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eTest-D365FlightServiceCatalogId\\nThis will open the web.config and check if the FlightingServiceCatalogID element is present or not.\",\n        \"Syntax\":  \"Test-D365FlightServiceCatalogId [[-AosServiceWebRootPath] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Test-D365LabelIdIsValid\",\n        \"Description\":  \"This function will validate if a string is a valid \\u0027Label Id\\u0027 format.\",\n        \"Params\":  [\n                       [\n                           \"LabelId\",\n                           \"The LabelId string thay you want to validate\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Alex Kwitny (@AlexOnDAX)\",\n        \"Synopsis\":  \"Checks if a string is a valid \\u0027Label Id\\u0027 format\",\n        \"Name\":  \"Test-D365LabelIdIsValid\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\u003eTest-D365LabelIdIsValid -LabelId \\\"ABC123\\\"\\nThis will test the if the LabelId is valid.\\r\\nIt will use the \\\"ABC123\\\" as the LabelId parameter.\\nThe expected result is $true\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\u003eTest-D365LabelIdIsValid -LabelId \\\"@ABC123\\\"\\nThis will test the if the LabelId is valid.\\r\\nIt will use the \\\"@ABC123\\\" as the LabelId parameter.\\nThe expected result is $true\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\u003eTest-D365LabelIdIsValid -LabelId \\\"@ABC123_1\\\"\\nThis will test the if the LabelId is valid.\\r\\nIt will use the \\\"@ABC123_1\\\" as the LabelId parameter.\\nThe expected result is $false\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\u003eTest-D365LabelIdIsValid -LabelId \\\"ABC.123\\\" #False\\nThis will test the if the LabelId is valid.\\r\\nIt will use the \\\"ABC.123\\\" as the LabelId parameter.\\nThe expected result is $false\",\n        \"Syntax\":  \"Test-D365LabelIdIsValid [-LabelId] \\u003cString\\u003e [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Update-D365BacpacModelFileSingleTable\",\n        \"Description\":  \"Update the \\\"model.xml\\\" file from inside the bacpac file to only handle a single table\\n\\nThis can be used to restore a single table as fast as possible to a new data\\n\\nThe table will be created like ordinary bacpac restore, expect it will only have the raw table definition and indexes, all other objects are dropped\\n\\nThe output can be used directly with the Import-D365Bacpac cmdlet and its ModelFile parameter, see the example sections for more details\",\n        \"Tags\":  [\n                     \"Bacpac\",\n                     \"Servicing\",\n                     \"Data\",\n                     \"SqlPackage\",\n                     \"Import\",\n                     \"Table\",\n                     \"Troubleshooting\"\n                 ],\n        \"Params\":  [\n                       [\n                           \"Path\",\n                           \"Path to the bacpac file that you want to work against\\nIt can also be a zip file\",\n                           \"File,ModelFile\",\n                           false,\n                           \"true (ByValue, ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"Table\",\n                           \"Name of the table that you want to be kept inside the model file when the update is done\",\n                           \"\",\n                           true,\n                           \"false\",\n                           \"\"\n                       ],\n                       [\n                           \"Schema\",\n                           \"Schema where the table that you want to work against exists\\nThe default value is \\\"dbo\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"dbo\"\n                       ],\n                       [\n                           \"OutputPath\",\n                           \"Path to where you want the updated bacpac model file to be saved\\nDefault value is: \\\"c:\\\\temp\\\\d365fo.tools\\\"\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DefaultTempPath\"\n                       ],\n                       [\n                           \"Force\",\n                           \"Switch to instruct the cmdlet to overwrite the bacpac model file specified in the OutputPath\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"False\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Mötz Jensen (@Splaxi)\",\n        \"Synopsis\":  \"Update the \\\"model.xml\\\" from the bacpac file to a single table\",\n        \"Name\":  \"Update-D365BacpacModelFileSingleTable\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eUpdate-D365BacpacModelFileSingleTable -Path \\\"c:\\\\temp\\\\d365fo.tools\\\\bacpac.model.xml\\\" -Table \\\"SalesTable\\\"\\nThis will create an updated bacpac.model.xml file with only the SalesTable to be imported.\\r\\nIt will read the \\\"c:\\\\temp\\\\d365fo.tools\\\\bacpac.model.xml\\\" file.\\r\\nIt will use the default \\\"dbo\\\" as the Schema parameter.\\r\\nIt will use the \\\"SalesTable\\\" as the Table parameter.\\r\\nIt will use the \\\"c:\\\\temp\\\\d365fo.tools\\\\dbo.salestable.model.xml\\\" as the default path for OutputPath parameter.\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eUpdate-D365BacpacModelFileSingleTable -Path \\\"c:\\\\temp\\\\d365fo.tools\\\\bacpac.model.xml\\\" -Table \\\"CommissionSalesGroup\\\" -Schema \\\"AX\\\"\\nThis will create an updated bacpac.model.xml file with only the \\\"CommissionSalesGroup\\\", from the \\\"AX\\\" schema, to be imported.\\r\\nIt will read the \\\"c:\\\\temp\\\\d365fo.tools\\\\bacpac.model.xml\\\" file.\\r\\nIt will use the \\\"AX\\\" as the Schema for the table.\\r\\nIt will use the \\\"CommissionSalesGroup\\\" as the Table parameter.\\r\\nIt will use the \\\"c:\\\\temp\\\\d365fo.tools\\\\ax.CommissionSalesGroup.model.xml\\\" as the default path for OutputPath parameter.\\n-------------------------- EXAMPLE 3 --------------------------\\nPS C:\\\\\\u003eUpdate-D365BacpacModelFileSingleTable -Path \\\"c:\\\\temp\\\\d365fo.tools\\\\bacpac.model.xml\\\" -Table \\\"SalesTable\\\" -OutputPath \\\"c:\\\\temp\\\\troubleshoot.xml\\\"\\nThis will create an updated bacpac.model.xml file with only the SalesTable to be imported.\\r\\nIt will read the \\\"c:\\\\temp\\\\d365fo.tools\\\\bacpac.model.xml\\\" file.\\r\\nIt will use the default \\\"dbo\\\" as the Schema parameter.\\r\\nIt will use the \\\"SalesTable\\\" as the Table parameter.\\r\\nIt will use the \\\"c:\\\\temp\\\\troubleshoot.xml\\\" as the path for OutputPath parameter.\\n-------------------------- EXAMPLE 4 --------------------------\\nPS C:\\\\\\u003eExport-D365BacpacModelFile -Path \\\"c:\\\\Temp\\\\AxDB.bacpac\\\" | Update-D365BacpacModelFileSingleTable -Table SalesTable\\nThis will create an updated bacpac.model.xml file with only the SalesTable to be imported.\\r\\nIt will read the bacpac model file generated from the Export-D365BacpacModelFile cmdlet.\\r\\nIt will use the default \\\"dbo\\\" as the Schema parameter.\\r\\nIt will use the \\\"SalesTable\\\" as the Table parameter.\\r\\nIt will use the \\\"c:\\\\temp\\\\d365fo.tools\\\\dbo.salestable.model.xml\\\" as the default path for OutputPath parameter.\\n-------------------------- EXAMPLE 5 --------------------------\\nPS C:\\\\\\u003eUpdate-D365BacpacModelFileSingleTable -Path \\\"c:\\\\temp\\\\d365fo.tools\\\\bacpac.model.xml\\\" -Table \\\"SalesTable\\\" -Force\\nThis will create an updated bacpac.model.xml file with only the SalesTable to be imported.\\r\\nIt will read the \\\"c:\\\\temp\\\\d365fo.tools\\\\bacpac.model.xml\\\" file.\\r\\nIt will use the default \\\"dbo\\\" as the Schema parameter.\\r\\nIt will use the \\\"SalesTable\\\" as the Table parameter.\\r\\nIt will use the \\\"c:\\\\temp\\\\d365fo.tools\\\\dbo.salestable.model.xml\\\" as the default path for OutputPath parameter.\\nIt will overwrite the \\\"c:\\\\temp\\\\d365fo.tools\\\\dbo.salestable.model.xml\\\" if it already exists.\",\n        \"Syntax\":  \"Update-D365BacpacModelFileSingleTable [[-Path] \\u003cString\\u003e] [-Table] \\u003cString\\u003e [[-Schema] \\u003cString\\u003e] [[-OutputPath] \\u003cString\\u003e] [-Force] [\\u003cCommonParameters\\u003e]\"\n    },\n    {\n        \"CommandName\":  \"Update-D365User\",\n        \"Description\":  \"Is capable of updating all the user details inside the UserInfo table to enable a user to sign in\",\n        \"Params\":  [\n                       [\n                           \"DatabaseServer\",\n                           \"The name of the database server\\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\\nIf Azure use the full address to the database server, e.g. server.database.windows.net\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseServer\"\n                       ],\n                       [\n                           \"DatabaseName\",\n                           \"The name of the database\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseName\"\n                       ],\n                       [\n                           \"SqlUser\",\n                           \"The login name for the SQL Server instance\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserName\"\n                       ],\n                       [\n                           \"SqlPwd\",\n                           \"The password for the SQL Server user\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"$Script:DatabaseUserPassword\"\n                       ],\n                       [\n                           \"Email\",\n                           \"The search string to select which user(s) should be updated.\\nThe parameter supports wildcards. E.g. -Email \\\"*@contoso.com*\\\"\",\n                           \"\",\n                           true,\n                           \"true (ByPropertyName)\",\n                           \"\"\n                       ],\n                       [\n                           \"Company\",\n                           \"The company the user should start in.\",\n                           \"\",\n                           false,\n                           \"false\",\n                           \"\"\n                       ]\n                   ],\n        \"Alias\":  \"\",\n        \"Author\":  \"Rasmus Andersen (@ITRasmus)\",\n        \"Synopsis\":  \"Updates the user details in the database\",\n        \"Name\":  \"Update-D365User\",\n        \"Links\":  null,\n        \"Examples\":  \"-------------------------- EXAMPLE 1 --------------------------\\nPS C:\\\\\\u003eUpdate-D365User -Email \\\"claire@contoso.com\\\"\\nThis will search for the user with the e-mail address claire@contoso.com and update it with needed information based on the tenant owner of the environment\\n-------------------------- EXAMPLE 2 --------------------------\\nPS C:\\\\\\u003eUpdate-D365User -Email \\\"*contoso.com\\\"\\nThis will search for all users with an e-mail address containing \\u0027contoso.com\\u0027 and update them with needed information based on the tenant owner of the environment\",\n        \"Syntax\":  \"Update-D365User [[-DatabaseServer] \\u003cString\\u003e] [[-DatabaseName] \\u003cString\\u003e] [[-SqlUser] \\u003cString\\u003e] [[-SqlPwd] \\u003cString\\u003e] [-Email] \\u003cString\\u003e [[-Company] \\u003cString\\u003e] [\\u003cCommonParameters\\u003e]\"\n    }\n]\n"
  },
  {
    "path": "d365fo.tools/bin/readme.md",
    "content": "﻿# bin folder\n\nThe bin folder exists to store binary data. And scripts related to the type system.\n\nThis may include your own C#-based library, third party libraries you want to include (watch the license!), or a script declaring type accelerators (effectively aliases for .NET types)\n\nFor more information on Type Accelerators, see the help on Set-PSFTypeAlias"
  },
  {
    "path": "d365fo.tools/d365fo.tools.psd1",
    "content": "﻿@{\n\t# Script module or binary module file associated with this manifest\n\tRootModule        = 'd365fo.tools.psm1'\n\n\t# Version number of this module.\n\tModuleVersion     = '0.7.10'\n\n\t# ID used to uniquely identify this module\n\tGUID              = '7c7b26d4-f764-4cb0-a692-459a0a689dbb'\n\n\t# Author of this module\n\tAuthor            = 'Mötz Jensen & Rasmus Andersen'\n\n\t# Company or vendor of this module\n\tCompanyName       = 'Essence Solutions'\n\n\t# Copyright statement for this module\n\tCopyright         = '(c) 2018 Mötz Jensen & Rasmus Andersen. All rights reserved.'\n\n\t# Description of the functionality provided by this module\n\tDescription       = 'A set of tools that will assist you when working with Dynamics 365 Finance & Operations development / demo machines.'\n\n\t# Minimum version of the Windows PowerShell engine required by this module\n\tPowerShellVersion = '5.0'\n\t\n\t# Modules that must be imported into the global environment prior to importing\n\t# this module.\n\t# To enable the GitHub dependency graph, changes should be synchronized with\n\t# https://github.com/d365collaborative/d365fo.tools/blob/master/.github/workflows/dependencies.yml\n\tRequiredModules   = @(\n\t\t@{ ModuleName = 'PSFramework'; ModuleVersion = '1.9.308' }\n\t\t, @{ ModuleName = 'Az.Storage'; ModuleVersion = '1.11.0' }\n\t\t, @{ ModuleName = 'PSOAuthHelper'; ModuleVersion = '0.3.0' }\n\t\t, @{ ModuleName = 'ImportExcel'; ModuleVersion = '7.1.0' }\n\t)\n\t\n\n\t# Assemblies that must be loaded prior to importing this module\n\t# RequiredAssemblies = @('bin\\d365fo.tools.dll')\n\n\t# Type files (.ps1xml) to be loaded when importing this module\n\t# TypesToProcess = @('xml\\d365fo.tools.Types.ps1xml')\n\n\t# Format files (.ps1xml) to be loaded when importing this module\n\tFormatsToProcess  = @('xml\\d365fo.tools.Format.ps1xml')\n\n\t# Functions to export from this module\n\tFunctionsToExport = @(\n\t\t'Add-D365AzureStorageConfig',\n\t\t'Add-D365BroadcastMessageConfig',\n\t\t'Add-D365ModuleToRemove',\n\t\t'Add-D365RsatWifConfigAuthorityThumbprint',\n\t\t'Add-D365WindowsDefenderRules',\n\n\t\t'Backup-D365DevConfig',\n\t\t'Backup-D365MetaDataDir',\n\t\t'Backup-D365Runbook',\n\t\t'Backup-D365WebConfig',\n\t\t'Backup-D365WifConfig',\n\n\t\t'Clear-D365ActiveBroadcastMessageConfig',\n\t\t'Clear-D365BacpacObject',\n\t\t'Clear-D365BacpacTableData',\n\t\t'Clear-D365MonitorData',\n\t\t'Clear-D365TempDbTables',\n\t\t'ConvertTo-D365Dacpac',\n\n\t\t'Disable-D365MaintenanceMode'\n\t\t'Disable-D365SqlChangeTracking',\n\t\t'Disable-D365User',\n\t\t'Disable-D365Flight',\n\t\t'Disable-D365Exception',\n\t\t'Disable-D365IISPreload',\n\t\t'Enable-D365Exception',\n\t\t'Enable-D365MaintenanceMode',\n\t\t'Enable-D365SqlChangeTracking',\n\t\t'Enable-D365User',\n\t\t'Enable-D365Flight',\n\t\t'Enable-D365IISPreload',\n\n\t\t'Export-D365BacpacModelFile',\n\t\t'Export-D365Model',\n\t\t'Export-D365SecurityDetails',\n\n\t\t'Find-D365Command',\n\n\t\t'Get-D365ActiveAzureStorageConfig',\n\t\t'Get-D365ActiveBroadcastMessageConfig',\n\n\t\t'Get-D365AOTObject',\n\n\t\t'Get-D365AzureDevOpsNuget',\n\n\t\t'Get-D365AzureStorageConfig',\n\t\t'Get-D365AzureStorageFile',\n\t\t'Get-D365AzureStorageUrl',\n\t\t'Get-D365BacpacSqlOptions',\n\t\t'Get-D365BacpacTable',\n\t\t'Get-D365BroadcastMessage',\n\t\t'Get-D365BroadcastMessageConfig',\n\n\t\t'Get-D365ClickOnceTrustPrompt',\n\t\t'Get-D365CompilerResult',\n\n\t\t'Get-D365Database',\n\t\t'Get-D365DatabaseAccess',\n\t\t'Get-D365DecryptedWebConfig',\n\t\t'Get-D365DefaultModelForNewProjects',\n\t\t'Get-D365DotNetClass',\n\t\t'Get-D365DotNetMethod',\n\n\t\t'Get-D365Environment',\n\t\t'Get-D365EnvironmentSettings',\n\t\t'Get-D365EventTraceProvider',\n\t\t'Get-D365ExternalIP',\n\n\t\t'Get-D365Flight',\n\t\t'Get-D365IISPreload',\n\n\t\t'Get-D365JsonService',\n\n\t\t'Get-D365InstalledHotfix',\n\t\t'Get-D365InstalledPackage',\n\t\t'Get-D365InstalledService',\n\t\t'Get-D365InstanceName',\n\n\t\t'Get-D365Label',\n\t\t'Get-D365Language',\n\t\t'Get-D365LabelFile',\n\t\t\t\t\t\t\n\t\t'Get-D365LcsApiConfig',\n\t\t'Get-D365LcsApiToken',\n\t\t'Get-D365LcsAssetFile',\n\t\t'Get-D365LcsSharedAssetFile',\n\t\t'Get-D365LcsAssetValidationStatus',\n\t\t'Get-D365LcsDatabaseBackups',\n\t\t'Get-D365LcsDatabaseOperationStatus',\n\t\t'Get-D365LcsDeploymentStatus',\n\t\t'Get-D365LcsEnvironmentHistory',\n\t\t'Get-D365LcsEnvironmentMetadata',\n\t\t'Get-D365LcsEnvironmentRsatCertificate',\n\n\t\t'Get-D365MaintenanceMode',\n\t\t'Get-D365Model',\n\t\t'Get-D365Module',\n\t\t'Get-D365OfflineAuthenticationAdminEmail',\n\n\t\t'Get-D365PackageBundleDetail',\n\t\t'Get-D365PackageLabelResourceFile',\n\t\t'Get-D365PackageLabelResources',\n\t\t'Get-D365ProductInformation',\n\n\t\t'Get-D365RsatCertificateThumbprint',\n\t\t'Get-D365RsatPlaybackFile',\n\t\t'Get-D365RsatSoapHostname',\n\n\t\t'Get-D365Runbook',\n\t\t'Get-D365RunbookId',\n\t\t'Get-D365RunbookLogFile',\n\n\t\t'Get-D365SDPCleanUp',\n\t\t'Get-D365SDPDetails',\n\n\t\t'Get-D365Table',\n\t\t'Get-D365TableField',\n\t\t'Get-D365TableSequence',\n\t\t'Get-D365TablesInChangedTracking',\n\t\t'Get-D365TfsUri',\n\t\t'Get-D365TfsWorkspace',\n\n\t\t'Get-D365Url',\n\t\t'Get-D365User',\n\t\t'Get-D365UserAuthenticationDetail',\n\n\t\t'Get-D365VisualStudioCompilerResult',\n\t\t'Get-D365WebServerType',\n\t\t'Get-D365WindowsActivationStatus',\n\n\t\t'Import-D365AadUser',\n\t\t'Import-D365AadApplication',\n\t\t'Import-D365Bacpac',\n\t\t'Import-D365Dacpac',\n\t\t'Import-D365Model',\n\t\t'Import-D365ExternalUser',\n\t\t'Import-D365RsatSelfServiceCertificates',\n\t\t\t\t\t\t\n\t\t'Initialize-D365RsatCertificate',\n\t\t\n\t\t'Install-D365SupportingSoftware',\n\n\t\t'Invoke-D365AzCopyTransfer',\n\t\t\t\t\t\t\n\t\t'Invoke-D365AzureDevOpsNugetPush',\n\t\t\t\t\t\t\n\t\t'Invoke-D365AzureStorageDownload',\n\t\t'Invoke-D365AzureStorageUpload',\n\n\t\t'Invoke-D365CompilerResultAnalyzer',\n\t\t\t\t\t\t\n\t\t'Invoke-D365DataFlush',\n\t\t'Invoke-D365DbSync',\n\t\t'Invoke-D365DbSyncPartial',\n\t\t'Invoke-D365DbSyncModule',\n\t\t\t\t\t\t\n\t\t'Invoke-D365GenerateReportAggregateDataEntity',\n\t\t'Invoke-D365GenerateReportAggregateMeasure',\n\t\t'Invoke-D365GenerateReportConfigKey',\n\t\t'Invoke-D365GenerateReportConfigKeyGroup',\n\t\t'Invoke-D365GenerateReportDataEntity',\n\t\t'Invoke-D365GenerateReportDataEntityField',\n\t\t'Invoke-D365GenerateReportKpi',\n\t\t'Invoke-D365GenerateReportLicenseCode',\n\t\t'Invoke-D365GenerateReportMenuItem',\n\t\t'Invoke-D365GenerateReports',\n\t\t'Invoke-D365GenerateReportSsrs',\n\t\t'Invoke-D365GenerateReportTable',\n\t\t'Invoke-D365GenerateReportWorkflowType'\n\t\t\t\t\t\t\n\t\t'Invoke-D365InstallAzCopy',\n\t\t'Invoke-D365InstallLicense',\n\t\t'Invoke-D365InstallNuget',\n\t\t'Invoke-D365InstallSqlPackage',\n\t\t\t\t\t\t\n\t\t'Invoke-D365LcsApiRefreshToken',\n\t\t'Invoke-D365LcsDatabaseExport',\n\t\t'Invoke-D365LcsDatabaseRefresh',\n\t\t'Invoke-D365LcsDeployment',\n\t\t'Invoke-D365LcsEnvironmentStart',\n\t\t'Invoke-D365LcsEnvironmentStop',\n\t\t'Invoke-D365LcsUpload',\n\n\t\t'Invoke-D365ModuleCompile',\n\t\t'Invoke-D365ModuleLabelGeneration',\n\t\t'Invoke-D365ModuleReportsCompile',\n\t\t'Invoke-D365ModuleFullCompile',\n\n\t\t'Invoke-D365ProcessModule'\n\n\t\t'Invoke-D365ReArmWindows',\n\t\t'Invoke-D365RunbookAnalyzer',\n\n\t\t'Invoke-D365SDPInstall',\n\t\t'Invoke-D365SDPInstallUDE',\n\t\t'Invoke-D365SCDPBundleInstall',\n\t\t'Invoke-D365SeleniumDownload',\n\t\t'Invoke-D365SysFlushAodCache',\n\t\t'Invoke-D365SysRunnerClass',\n\t\t'Invoke-D365SqlScript',\n\n\t\t'Invoke-D365VisualStudioCompilerResultAnalyzer',\n\t\t'Invoke-D365WinRmCertificateRotation',\n\t\t\t\t\t\t\n\t\t'Invoke-D365TableBrowser',\n\n\t\t'Invoke-D365BestPractice',\n\n\t\t'New-D365Bacpac',\n\t\t'New-D365CAReport',\n\t\t'New-D365EntraIntegration',\n\t\t'New-D365ISVLicense',\n\t\t'New-D365ModuleToRemove',\n\t\t'New-D365TopologyFile',\n\n\t\t'Publish-D365WebResources',\n\t\t'Publish-D365SsrsReport',\n\n\t\t'Register-D365AzureStorageConfig',\n\t\t\n\t\t'Remove-D365LcsAssetFile',\n\t\t'Remove-D365BroadcastMessageConfig',\n\t\t'Remove-D365Database',\n\t\t'Remove-D365Model',\n\t\t'Remove-D365User',\n\n\t\t'Rename-D365Instance',\n\t\t'Rename-D365ComputerName',\n\n\t\t'Repair-D365BacpacModelFile',\n\t\t\n\t\t'Restart-D365Environment',\n\n\t\t'Restore-D365DevConfig',\n\t\t'Restore-D365WebConfig',\n\n\t\t'Send-D365BroadcastMessage',\n\n\t\t'Set-D365ActiveAzureStorageConfig',\n\t\t'Set-D365ActiveBroadcastMessageConfig',\n\n\t\t'Set-D365Admin',\n\n\t\t'Set-D365AzCopyPath',\n\n\t\t'Set-D365ClickOnceTrustPrompt',\n\n\t\t'Set-D365DefaultModelForNewProjects',\n\n\t\t'Set-D365FavoriteBookmark',\n\t\t'Set-D365LcsApiConfig',\n\t\t\t\t\t\t\n\t\t'Set-D365NugetPath',\n\n\t\t'Set-D365OfflineAuthenticationAdminEmail',\n\t\t\t\t\t\t\n\t\t'Set-D365RsatTier2Crypto',\n\t\t'Set-D365RsatConfiguration',\n\t\t\t\t\t\t\n\t\t'Set-D365SDPCleanUp',\n\t\t'Set-D365StartPage',\n\t\t'Set-D365SqlPackagePath',\n\t\t'Set-D365SysAdmin',\n\n\t\t'Set-D365WebConfigDatabase',\n\t\t'Set-D365WebServerType',\n\n\t\t'Set-D365TraceParserFileSize',\n\n\t\t'Set-D365WorkstationMode',\n\n\t\t'Set-D365FlightServiceCatalogId',\n\n\t\t'Start-D365Environment',\n\t\t'Start-D365EnvironmentV2',\n\t\t'Start-D365EventTrace',\n\n\t\t'Stop-D365Environment',\n\t\t'Stop-D365EventTrace',\n\n\t\t'Switch-D365ActiveDatabase',\n\n\t\t'Test-D365Command',\n\t\t'Test-D365DataverseConnection',\n\t\t'Test-D365EntraIntegration',\n\t\t'Test-D365FlightServiceCatalogId',\n\t\t'Test-D365LabelIdIsValid',\n\t\t\t\t\t\t\n\t\t'Update-D365BacpacModelFileSingleTable',\n\t\t'Update-D365User'\n\t)\n\n\t# Cmdlets to export from this module\n\tCmdletsToExport   = ''\n\n\t# Variables to export from this module\n\tVariablesToExport = ''\n\n\t# Aliases to export from this module\n\tAliasesToExport   = @(\n\t\t'Initialize-D365TestAutomationCertificate'\n\t\t, 'Add-D365WIFConfigAuthorityThumbprint'\n\t\t, 'Invoke-D365SqlCmd'\n\t\t, 'Get-D365ModelFileFromBacpac'\n\t\t, 'Get-D365SqlOptionsFromBacpacModelFile'\n\t\t, 'Clear-D365TableDataFromBacpac'\n\t)\n\n\t# List of all modules packaged with this module\n\tModuleList        = @()\n\n\t# List of all files packaged with this module\n\tFileList          = @()\n\n\t# Private data to pass to the module specified in ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.\n\tPrivateData       = @{\n\n\t\t#Support for PowerShellGet galleries.\n\t\tPSData = @{\n\t\t\t# Tags applied to this module. These help with module discovery in online galleries.\n\t\t\tTags                       = @('d365fo', 'Dynamics365', 'D365', 'Finance&Operations', 'FinanceOperations', 'FinanceAndOperations', 'Dynamics365FO')\n\n\t\t\t# A URL to the license for this module.\n\t\t\tLicenseUri                 = \"https://opensource.org/licenses/MIT\"\n\n\t\t\t# A URL to the main website for this project.\n\t\t\tProjectUri                 = 'https://github.com/d365collaborative/d365fo.tools'\n\n\t\t\t# A URL to an icon representing this module.\n\t\t\t# IconUri = ''\n\n\t\t\t# ReleaseNotes of this module\n\t\t\t# ReleaseNotes = ''\n\n\t\t\t# Indicates this is a pre-release/testing version of the module.\n\t\t\tIsPrerelease               = 'True'\n\n\t\t\tExternalModuleDependencies = @('PSDiagnostics')\n\n\t\t} # End of PSData hashtable\n\n\t} # End of PrivateData hashtable\n}\n"
  },
  {
    "path": "d365fo.tools/d365fo.tools.psm1",
    "content": "﻿$script:ModuleRoot = $PSScriptRoot\n$script:ModuleVersion = \"0.7.10\"\n\n# Detect whether at some level dotsourcing was enforced\n$script:doDotSource = Get-PSFConfigValue -FullName d365fo.tools.Import.DoDotSource -Fallback $false\nif ($d365fo.tools_dotsourcemodule) { $script:doDotSource = $true }\n\n<#\nNote on Resolve-Path:\nAll paths are sent through Resolve-Path/Resolve-PSFPath in order to convert them to the correct path separator.\nThis allows ignoring path separators throughout the import sequence, which could otherwise cause trouble depending on OS.\nResolve-Path can only be used for paths that already exist, Resolve-PSFPath can accept that the last leaf my not exist.\nThis is important when testing for paths.\n#>\n\n# Detect whether at some level loading individual module files, rather than the compiled module was enforced\n$importIndividualFiles = Get-PSFConfigValue -FullName d365fo.tools.Import.IndividualFiles -Fallback $false\nif ($d365fo.tools_importIndividualFiles) { $importIndividualFiles = $true }\nif (Test-Path (Resolve-PSFPath -Path \"$($script:ModuleRoot)\\..\\.git\" -SingleItem -NewChild)) { $importIndividualFiles = $true }\nif (-not (Test-Path (Resolve-PSFPath \"$($script:ModuleRoot)\\commands.ps1\" -SingleItem -NewChild))) { $importIndividualFiles = $true }\n\nfunction Import-ModuleFile\n{\n\t<#\n\t\t.SYNOPSIS\n\t\t\tLoads files into the module on module import.\n\n\t\t.DESCRIPTION\n\t\t\tThis helper function is used during module initialization.\n\t\t\tIt should always be dotsourced itself, in order to proper function.\n\n\t\t\tThis provides a central location to react to files being imported, if later desired\n\n\t\t.PARAMETER Path\n\t\t\tThe path to the file to load\n\n\t\t.EXAMPLE\n\t\t\tPS C:\\> . Import-ModuleFile -File $function.FullName\n\n\t\t\tImports the file stored in $function according to import policy\n\t#>\n\t[CmdletBinding()]\n\tParam (\n\t\t[string]\n\t\t$Path\n\t)\n\n\tif ($doDotSource) { . (Resolve-Path $Path) }\n\telse { $ExecutionContext.InvokeCommand.InvokeScript($false, ([scriptblock]::Create([io.file]::ReadAllText((Resolve-Path $Path)))), $null, $null) }\n}\n\nif ($importIndividualFiles)\n{\n\t# Execute Preimport actions\n\t. Import-ModuleFile -Path \"$ModuleRoot\\internal\\scripts\\preimport.ps1\"\n\n\t# Import all internal functions\n\tforeach ($function in (Get-ChildItem \"$ModuleRoot\\internal\\functions\" -Filter \"*.ps1\" -Recurse -ErrorAction Ignore))\n\t{\n\t\t. Import-ModuleFile -Path $function.FullName\n\t}\n\n\t# Import all public functions\n\tforeach ($function in (Get-ChildItem \"$ModuleRoot\\functions\" -Filter \"*.ps1\" -Recurse -ErrorAction Ignore))\n\t{\n\t\t. Import-ModuleFile -Path $function.FullName\n\t}\n\n\t# Execute Postimport actions\n\t. Import-ModuleFile -Path \"$ModuleRoot\\internal\\scripts\\postimport.ps1\"\n}\nelse\n{\n\tif (Test-Path (Resolve-PSFPath \"$($script:ModuleRoot)\\resourcesBefore.ps1\" -SingleItem -NewChild))\n\t{\n\t\t. Import-ModuleFile -Path \"$($script:ModuleRoot)\\resourcesBefore.ps1\"\n\t}\n\n\t. Import-ModuleFile -Path \"$($script:ModuleRoot)\\commands.ps1\"\n\n\tif (Test-Path (Resolve-PSFPath \"$($script:ModuleRoot)\\resourcesAfter.ps1\" -SingleItem -NewChild))\n\t{\n\t\t. Import-ModuleFile -Path \"$($script:ModuleRoot)\\resourcesAfter.ps1\"\n\t}\n}\n"
  },
  {
    "path": "d365fo.tools/en-us/about_Deployable_Packages.help.txt",
    "content": "﻿TOPIC\n    about_Deployable_Packages\n\nSHORT DESCRIPTION\n    Describes the concept of deployable packages and how to work with them using the d365fo.tools.\n\nLONG DESCRIPTION\n    \"A deployable package is a unit of deployment that can be applied to any environment. It can consist of a binary hotfix to the runtime components of Application Object Server (AOS), an updated application package, or a new application package.\"\n    - Install deployable packages from the command line (https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/deployment/install-deployable-package)\n\n    The link above to the Microsoft documentation provides further guidance on how to install deployable packages on environments that cannot be updated using Lifecylce Services (LCS). This is a multi-step process which can be error prone if not done regularly or automated in some way.\n\n    The d365fo.tools provide a collection of cmdlets that wrap this process in some easy to use PowerShell commands. The names of the cmdlets contain some terms, which are briefly explained:\n\n    - SDP: short for Software Deployable Package\n    - Runbook: A runbook is a xml file created during the install process. It defines all the steps that will be executed by the installer.\n    - Topology: A topology is another xml file that defines the components of the D365FO environment. The runbook is created based on the topology.\n\n    The following gives an overview of the available cmdlets. Further information for each cmdlet is available in its help.\n\nInvoke-D365SDPInstall\n    The Invoke-D365SDPInstall cmdlet is the main command used to install a deployable package.\n\nNew-D365TopologyFile\n    Used to create a topology xml file. Note that this is done by the Invoke-D365SDPInstall cmdlet automatically, so this command is usually used if the topology file is needed for something else than the installation of a deployable package. It can for example be useful to compare two different environments.\n\nGet-D365InstalledService\n    Used to retrieve a list of services available in a D365FO environment. The output can be used as the -Services parameter of the New-D365TopologyFile command.\n\nGet-D365InstalledPackage\n    Used to retrieve a list of packages available in a D365FO environment.\n\nSet-D365SDPCleanUp and Get-D365SDPCleanUp\n    These two commands provide an easy way to change or view the Windows registry entries that control how soon the contents of the folder where deployable packages are stored are deleted. This folder is used on cloud hosted environments by the updates done through LCS.\n\nGet-D365Runbook\n    Used to retrieve a list of runbook files that are available on a D365FO environment. The output can be piped to other cmdlets that work with runbooks.\n\nGet-D365RunbookId\n    Used to retrieve the id of a runbook from a runbook file.\n\nInvoke-D365RunbookAnalyzer\n    Used to analyze the issues of a failed runbook.\n\nGet-D365RunbookLogFile\n    Used to retrieve the log file from the installation folder of a package for specific installation step.\n\nBackup-D365Runbook\n    Used to create a backup of a runbook file.\n\nKEYWORDS\n    DeployablePackage, Runbook\n\nSEE ALSO\n    Guide \"Work with packages, resource label files, language and labels\" (https://github.com/d365collaborative/d365fo.tools/wiki/Work-with-packages,-resource---label-files,-language-and-lables)"
  },
  {
    "path": "d365fo.tools/en-us/about_d365fo.tools.help.txt",
    "content": "﻿TOPIC\n\tabout_d365fo.tools\n\t\nSHORT DESCRIPTION\n\tExplains how to use the d365fo.tools powershell module\n\t\nLONG DESCRIPTION\n\t<Insert Content here>\n\nKEYWORDS\n\td365fo.tools"
  },
  {
    "path": "d365fo.tools/functions/add-d365azurestorageconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Save an Azure Storage Account config\n        \n    .DESCRIPTION\n        Adds an Azure Storage Account config to the configuration store\n        \n    .PARAMETER Name\n        The logical name of the Azure Storage Account you are about to registered in the configuration store\n        \n    .PARAMETER AccountId\n        The account id for the Azure Storage Account you want to register in the configuration store\n        \n    .PARAMETER AccessToken\n        The access token for the Azure Storage Account you want to register in the configuration store\n        \n    .PARAMETER SAS\n        The SAS key that you have created for the storage account or blob container\n        \n    .PARAMETER Container\n        The name of the blob container inside the Azure Storage Account you want to register in the configuration store\n        \n    .PARAMETER Temporary\n        Instruct the cmdlet to only temporarily add the azure storage account configuration in the configuration store\n        \n    .PARAMETER Force\n        Switch to instruct the cmdlet to overwrite already registered Azure Storage Account entry\n        \n    .EXAMPLE\n        PS C:\\> Add-D365AzureStorageConfig -Name \"UAT-Exports\" -AccountId \"1234\" -AccessToken \"dafdfasdfasdf\" -Container \"testblob\"\n        \n        This will add an entry into the list of Azure Storage Accounts that is stored with the name \"UAT-Exports\" with AccountId \"1234\", AccessToken \"dafdfasdfasdf\" and blob container \"testblob\".\n        \n    .EXAMPLE\n        PS C:\\> Add-D365AzureStorageConfig -Name UAT-Exports -SAS \"sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" -AccountId \"1234\" -Container \"testblob\"\n        \n        This will add an entry into the list of Azure Storage Accounts that is stored with the name \"UAT-Exports\" with AccountId \"1234\", SAS \"sv=2018-03-28&si=unlisted&sr=c&sig=AUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" and blob container \"testblob\".\n        The SAS key enables you to provide explicit access to a given blob container inside an Azure Storage Account.\n        The SAS key can easily be revoked and that way you have control over the access to the container and its content.\n        \n    .EXAMPLE\n        PS C:\\> Add-D365AzureStorageConfig -Name UAT-Exports -SAS \"sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" -AccountId \"1234\" -Container \"testblob\" -Temporary\n        \n        This will add an entry into the list of Azure Storage Accounts that is stored with the name \"UAT-Exports\" with AccountId \"1234\", SAS \"sv=2018-03-28&si=unlisted&sr=c&sig=AUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" and blob container \"testblob\".\n        The SAS key enables you to provide explicit access to a given blob container inside an Azure Storage Account.\n        The SAS key can easily be revoked and that way you have control over the access to the container and its content.\n        \n        The configuration will only last for the rest of this PowerShell console session.\n        \n    .NOTES\n        Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, Container\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Add-D365AzureStorageConfig {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $Name,\n\n        [Parameter(Mandatory = $true)]\n        [string] $AccountId,\n\n        [Parameter(Mandatory = $true, ParameterSetName = \"AccessToken\")]\n        [string] $AccessToken,\n\n        [Parameter(Mandatory = $true, ParameterSetName = \"SAS\")]\n        [string] $SAS,\n\n        [Parameter(Mandatory = $true)]\n        [Alias('Blob')]\n        [Alias('Blobname')]\n        [string] $Container,\n\n        [switch] $Temporary,\n\n        [switch] $Force\n    )\n    \n    $Details = @{AccountId = $AccountId.ToLower();\n        Container          = $Container.ToLower();\n    }\n\n    if ($PSCmdlet.ParameterSetName -eq \"AccessToken\") { $Details.AccessToken = $AccessToken }\n    if ($PSCmdlet.ParameterSetName -eq \"SAS\") {\n        if ($SAS.StartsWith(\"?\")) {\n            $SAS = $SAS.Substring(1)\n        }\n\n        $Details.SAS = $SAS\n    }\n\n    $Accounts = [hashtable](Get-PSFConfigValue -FullName \"d365fo.tools.azure.storage.accounts\")\n\n    if ($Accounts.ContainsKey($Name)) {\n        if ($Force) {\n            $Accounts[$Name] = $Details\n\n            Set-PSFConfig -FullName \"d365fo.tools.azure.storage.accounts\" -Value $Accounts\n        }\n        else {\n            Write-PSFMessage -Level Host -Message \"An Azure Storage Account with that name <c='em'>already exists</c>. If you want to <c='em'>overwrite</c> the already registered details please supply the <c='em'>-Force</c> parameter.\"\n            Stop-PSFFunction -Message \"Stopping because an Azure Storage Account already exists with that name.\"\n            return\n        }\n    }\n    else {\n        $null = $Accounts.Add($Name, $Details)\n\n        Set-PSFConfig -FullName \"d365fo.tools.azure.storage.accounts\" -Value $Accounts\n    }\n\n    if (-not $Temporary) { Register-PSFConfig -FullName \"d365fo.tools.azure.storage.accounts\" -Scope UserDefault }\n}"
  },
  {
    "path": "d365fo.tools/functions/add-d365broadcastmessageconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Save a broadcast message config\n        \n    .DESCRIPTION\n        Adds a broadcast message config to the configuration store\n        \n    .PARAMETER Name\n        The logical name of the broadcast configuration you are about to register in the configuration store\n        \n    .PARAMETER Tenant\n        Azure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to send a message to\n        \n    .PARAMETER URL\n        URL / URI for the D365FO environment you want to send a message to\n        \n    .PARAMETER ClientId\n        The ClientId obtained from the Azure Portal when you created a Registered Application\n        \n    .PARAMETER ClientSecret\n        The ClientSecret obtained from the Azure Portal when you created a Registered Application\n        \n    .PARAMETER TimeZone\n        Id of the Time Zone your environment is running in\n        \n        You might experience that the local VM running the D365FO is running another Time Zone than the computer you are running this cmdlet from\n        \n        All available .NET Time Zones can be traversed with tab for this parameter\n        \n        The default value is \"UTC\"\n        \n    .PARAMETER EndingInMinutes\n        Specify how many minutes into the future you want this message / maintenance window to last\n        \n        Default value is 60 minutes\n        \n        The specified StartTime will always be based on local Time Zone. If you specify a different Time Zone than the local computer is running, the start and end time will be calculated based on your selection.\n        \n    .PARAMETER OnPremise\n        Specify if environnement is an D365 OnPremise\n        \n        Default value is \"Not set\" (= Cloud Environnement)\n        \n    .PARAMETER Temporary\n        Instruct the cmdlet to only temporarily add the broadcast message configuration in the configuration store\n        \n    .PARAMETER Force\n        Instruct the cmdlet to overwrite the broadcast message configuration with the same name\n        \n    .EXAMPLE\n        PS C:\\> Add-D365BroadcastMessageConfig -Name \"UAT\" -Tenant \"e674da86-7ee5-40a7-b777-1111111111111\" -URL \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" -ClientId \"dea8d7a9-1602-4429-b138-111111111111\" -ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\"\n        \n        This will create a new broadcast message configuration with the name \"UAT\".\n        It will save \"e674da86-7ee5-40a7-b777-1111111111111\" as the Azure Active Directory guid.\n        It will save \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" as the D365FO environment.\n        It will save \"dea8d7a9-1602-4429-b138-111111111111\" as the ClientId.\n        It will save \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\" as ClientSecret.\n        It will use the default value \"UTC\" Time Zone for converting the different time and dates.\n        It will use the default end time which is 60 minutes.\n        \n    .EXAMPLE\n        PS C:\\> Add-D365BroadcastMessageConfig -Name \"UAT\" -OnPremise -Tenant \"https://adfs.local/adfs\" -URL \"https://ax-sandbox.d365fo.local\" -ClientId \"dea8d7a9-1602-4429-b138-111111111111\" -ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\"\n        \n        This will create a new broadcast message configuration with the name \"UAT\".\n        It will target an OnPremise environment.\n        It will save \"https://adfs.local/adfs\" as the OAuth Tenant Provider.\n        It will save \"https://ax-sandbox.d365fo.local\" as the D365FO environment.\n        It will save \"dea8d7a9-1602-4429-b138-111111111111\" as the ClientId.\n        It will save \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\" as ClientSecret.\n        It will use the default value \"UTC\" Time Zone for converting the different time and dates.\n        It will use the default end time which is 60 minutes.\n        \n    .NOTES\n        Tags: Servicing, Broadcast, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n    .LINK\n        Clear-D365ActiveBroadcastMessageConfig\n        \n    .LINK\n        Get-D365ActiveBroadcastMessageConfig\n        \n    .LINK\n        Get-D365BroadcastMessageConfig\n        \n    .LINK\n        Remove-D365BroadcastMessageConfig\n        \n    .LINK\n        Send-D365BroadcastMessage\n        \n    .LINK\n        Set-D365ActiveBroadcastMessageConfig\n#>\n\nfunction Add-D365BroadcastMessageConfig {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $Name,\n\n        [Alias('$AADGuid')]\n        [string] $Tenant,\n\n        [Alias('URI')]\n        [string] $URL,\n\n        [string] $ClientId,\n\n        [string] $ClientSecret,\n\n        [string] $TimeZone = \"UTC\",\n\n        [int] $EndingInMinutes = 60,\n\n        [switch] $OnPremise,\n\n        [switch] $Temporary,\n\n        [switch] $Force\n    )\n\n    if (((Get-PSFConfig -FullName \"d365fo.tools.broadcast.*.name\").Value -contains $Name) -and (-not $Force)) {\n        Write-PSFMessage -Level Host -Message \"A broadcast message configuration with <c='em'>$Name</c> as name <c='em'>already exists</c>. If you want to <c='em'>overwrite</c> the current configuration, please supply the <c='em'>-Force</c> parameter.\"\n        Stop-PSFFunction -Message \"Stopping because a broadcast message configuration already exists with that name.\"\n        return\n    }\n\n    $configName = \"\"\n\n    #The ':keys' label is used to have a continue inside the switch statement itself\n    :keys foreach ($key in $PSBoundParameters.Keys) {\n        \n        $configurationValue = $PSBoundParameters.Item($key)\n        $configurationName = $key.ToLower()\n        $fullConfigName = \"\"\n\n        Write-PSFMessage -Level Verbose -Message \"Working on $key with $configurationValue\" -Target $configurationValue\n        \n        switch ($key) {\n            \"Name\" {\n                $configName = $Name.ToLower()\n                $fullConfigName = \"d365fo.tools.broadcast.$configName.name\"\n            }\n\n            {\"Temporary\",\"Force\" -contains $_} {\n                continue keys\n            }\n\n            \"TimeZone\" {\n                $timeZoneFound = Get-TimeZone -InputObject $TimeZone\n\n                if (Test-PSFFunctionInterrupt) { return }\n                \n                $fullConfigName = \"d365fo.tools.broadcast.$configName.$configurationName\"\n                $configurationValue = $timeZoneFound.Id\n            }\n\n            Default {\n                $fullConfigName = \"d365fo.tools.broadcast.$configName.$configurationName\"\n            }\n        }\n\n        Write-PSFMessage -Level Verbose -Message \"Setting $fullConfigName to $configurationValue\" -Target $configurationValue\n        Set-PSFConfig -FullName $fullConfigName -Value $configurationValue\n        if (-not $Temporary) { Register-PSFConfig -FullName $fullConfigName -Scope UserDefault }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/add-d365moduletoremove.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Adds a ModuleToRemove.txt file to a deployable package\n        \n    .DESCRIPTION\n        Modifies an existing deployable package and adds a ModuleToRemove.txt file to it.\n        \n    .PARAMETER ModuleToRemove\n        Path to the ModuleToRemove.txt file that you want to have inside a deployable package\n        \n    .PARAMETER DeployablePackage\n        Path to the deployable package file where the ModuleToRemove.txt file should be added\n        \n    .PARAMETER OutputPath\n        Path where you want the generated deployable package to be stored\n        \n        Default value is the same as the \"DeployablePackage\" parameter\n        \n    .EXAMPLE\n        PS C:\\> Add-D365ModuleToRemove -ModuleToRemove \"C:\\temp\\ModuleToRemove.txt\" -DeployablePackage \"C:\\temp\\DeployablePackage.zip\"\n        \n        This will take the \"C:\\temp\\ModuleToRemove.txt\" file and add it to the \"C:\\temp\\DeployablePackage.zip\" deployable package in the \"AOSService/Scripts\" folder.\n        \n    .EXAMPLE\n        PS C:\\> New-D365ModuleToRemove -Path C:\\Temp -Modules \"MyRemovedModule1\",\"MySecondRemovedModule\" | Add-D365ModuleToRemove -DeployablePackage C:\\Temp\\DeployablePackage.zip\n        \n        This will create a new ModuleToRemove.txt file and fill in \"MyRemovedModule1\" and \"MySecondRemovedModule\" as the modules to remove. The file is then added to the \"C:\\Temp\\DeployablePackage.zip\" deployable package.\n        \n    .LINK\n        New-D365ModuleToRemove\n        \n    .NOTES\n        Author: Florian Hopfner (@FH-Inway)\n        \n#>\nfunction Add-D365ModuleToRemove {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n\n        [Parameter(\n            Mandatory = $true,\n            Position = 1,\n            ValueFromPipelineByPropertyName = $true)]\n        [string] $ModuleToRemove,\n\n        [Parameter(Mandatory = $true, Position = 2)]\n        [string] $DeployablePackage,\n\n        [string] $OutputPath = $DeployablePackage\n\n    )\n\n    begin {\n        $oldprogressPreference = $global:progressPreference\n        $global:progressPreference = 'silentlyContinue'\n    }\n\n    process {\n        Add-FileToPackage -File $ModuleToRemove -Archive $DeployablePackage -Path \"AosService\\Scripts\" -OutputPath $OutputPath\n    }\n\n    end {\n        $global:progressPreference = $oldprogressPreference\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/add-d365rsatwifconfigauthoritythumbprint.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Add a certificate thumbprint to the wif.config.\n        \n    .DESCRIPTION\n        Register a certificate thumbprint in the wif.config file.\n        This can be useful for example when configuring RSAT on a local machine and add the used certificate thumbprint to that AOS.s\n        \n    .PARAMETER CertificateThumbprint\n        The thumbprint value of the certificate that you want to register in the wif.config file\n        \n    .EXAMPLE\n        PS C:\\> Add-D365RsatWifConfigAuthorityThumbprint -CertificateThumbprint \"12312323r424\"\n        \n        This will open the wif.config file and insert the \"12312323r424\" thumbprint value into the file.\n        \n    .NOTES\n        Tags: RSAT, Certificate, Testing, Regression Suite Automation Test, Regression, Test, Automation\n        \n        Author: Kenny Saelen (@kennysaelen)\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Add-D365RsatWifConfigAuthorityThumbprint {\n    [Alias(\"Add-D365WIFConfigAuthorityThumbprint\")]\n\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true, Position = 1)]\n        [string]$CertificateThumbprint\n    )\n      \n\n    try\n    {\n        $wifConfigFile = Join-Path $script:ServiceDrive \"\\AOSService\\webroot\\wif.config\"\n\n        if($true -eq (Test-Path -Path $wifConfigFile))\n        {\n            [xml]$wifXml = Get-Content $wifConfigFile\n\n            $authorities = $wifXml.SelectNodes('//system.identityModel//identityConfiguration//securityTokenHandlers//securityTokenHandlerConfiguration//issuerNameRegistry//authority[@name=\"https://fakeacs.accesscontrol.windows.net/\"]')\n            \n            if($authorities.Count -lt 1)\n            {\n                Write-PSFMessage -Level Critical -Message \"Only one authority should be found with the name https://fakeacs.accesscontrol.windows.net/\"\n                Stop-PSFFunction -Message  \"Stopping because an invalid authority structure was found in the wif.config file.\"\n                return\n            }\n            else\n            {\n                foreach ($authority in $authorities)\n                {\n                    $addElem = $wifXml.CreateElement(\"add\")\n                    $addAtt = $wifXml.CreateAttribute(\"thumbprint\")\n                    $addAtt.Value = $CertificateThumbprint\n                    $addElem.Attributes.Append($addAtt)\n                    $authority.FirstChild.AppendChild($addElem)\n                    $wifXml.Save($wifConfigFile)\n                }\n            }\n        }\n        else\n        {\n            Write-PSFMessage -Level Critical -Message \"The wif.config file would not be located on the system.\"\n            Stop-PSFFunction -Message  \"Stopping because the wif.config file could not be located.\"\n            return\n        }\n    }\n    catch\n    {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while configuring the certificates and the Windows Identity Foundation configuration for the AOS\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n        return\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/add-d365windowsdefenderrules.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Add rules to Windows Defender to enhance performance during development.\n        \n    .DESCRIPTION\n        Add rules to the Windows Defender to exclude Visual Studio, D365 Batch process, D365 Sync process, XPP related processes and SQL Server processes from scans and monitoring.\n        This will lead to performance gains because the Windows Defender stops to scan every file accessed by e.g. the MSBuild process, the cache and things around Visual Studio.\n        Supports rules for VS 2015 and VS 2019.\n        \n    .PARAMETER Silent\n        Instruct the cmdlet to silence the output written to the console\n        \n        If set the output will be silenced, if not set, the output will be written to the console\n        \n    .EXAMPLE\n        PS C:\\> Add-D365WindowsDefenderRules\n        \n        This will add the most common rules to the Windows Defender as exceptions.\n        All output will be written to the console.\n        \n    .EXAMPLE\n        PS C:\\> Add-D365WindowsDefenderRules -Silent\n        \n        This will add the most common rules to the Windows Defender as exceptions.\n        All output will be silenced and not outputted to the console.\n        \n    .NOTES\n        Tags: DevTools, Developer, Performance\n        \n        Author: Robin Kretzschmar (@darksmile92)\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        Author: Florian Hopfner (@FH-Inway)\n#>\nfunction Add-D365WindowsDefenderRules {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    param (\n        [switch] $Silent\n    )\n\n    $DefenderEnabled = Get-WindowsDefenderStatus -Silent:$Silent\n\n    if ($DefenderEnabled -eq $false) {\n        Write-PSFMessage -Level Host -Message \"Windows Defender is not enabled on this machine.\"\n        Stop-PSFFunction -Message \"Stopping because of errors.\"\n        return\n    }\n\n    try {\n        $AOSServicePath = Join-Path $script:ServiceDrive \"\\AOSService\"\n        $AOSPath = Join-Path $script:ServiceDrive \"\\AOSService\\webroot\\bin\"\n\n        if (-not (Test-PathExists -Path $AOSServicePath -Type Container)) { return }\n        \n        # visual studio & tools\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Professional\\Common7\\IDE\\devenv.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Professional\\Common7\\IDE\\Extensions\\TestPlatform\\testhost.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Enterprise\\Common7\\IDE\\devenv.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Enterprise\\Common7\\IDE\\Extensions\\TestPlatform\\testhost.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Professional\\Common7\\IDE\\devenv.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Professional\\Common7\\IDE\\qtagent32_40.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Professional\\Common7\\IDE\\Extensions\\TestPlatform\\testhost.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Professional\\Common7\\IDE\\CommonExtensions\\Microsoft\\TestWindow\\vstest.console.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\IDE\\devenv.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\IDE\\qtagent32_40.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\IDE\\Extensions\\TestPlatform\\testhost.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\IDE\\CommonExtensions\\Microsoft\\TestWindow\\vstest.console.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\devenv.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files\\Microsoft Visual Studio\\2022\\Professional\\Common7\\IDE\\devenv.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files\\Microsoft Visual Studio\\2022\\Professional\\Common7\\IDE\\qtagent32_40.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files\\Microsoft Visual Studio\\2022\\Professional\\Common7\\IDE\\Extensions\\TestPlatform\\testhost.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files\\Microsoft Visual Studio\\2022\\Professional\\Common7\\IDE\\CommonExtensions\\Microsoft\\TestWindow\\vstest.console.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Common7\\IDE\\devenv.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Common7\\IDE\\qtagent32_40.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Common7\\IDE\\Extensions\\TestPlatform\\testhost.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Common7\\IDE\\CommonExtensions\\Microsoft\\TestWindow\\vstest.console.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\MSBuild.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\MSBuild.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files (x86)\\MSBuild\\14.0\\Bin\\MSBuild.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files\\dotnet\\dotnet.exe\"\n        # customize path for cloud machines\n        Add-MpPreference -ExclusionProcess \"$Script:BinDir\\xppcAgent.exe\"\n        Add-MpPreference -ExclusionProcess \"$Script:BinDir\\SyncEngine.exe\"\n        Add-MpPreference -ExclusionProcess \"$Script:BinDir\\bin\\LabelC.exe\"\n        Add-MpPreference -ExclusionProcess \"$Script:BinDir\\bin\\SyncEngine.exe\"\n        Add-MpPreference -ExclusionProcess \"$Script:BinDir\\bin\\xppbp.exe\"\n        Add-MpPreference -ExclusionProcess \"$Script:BinDir\\bin\\xppc.dll\"\n        Add-MpPreference -ExclusionProcess \"$Script:BinDir\\bin\\xppc.exe\"\n        Add-MpPreference -ExclusionProcess \"$Script:BinDir\\bin\\xppcAgent.exe\"\n        Add-MpPreference -ExclusionProcess \"$Script:BinDir\\bin\\xppcAgent.17.0.exe\"\n        Add-MpPreference -ExclusionProcess \"$Script:BinDir\\bin\\xpppfagen.exe\"\n        Add-MpPreference -ExclusionProcess \"$AOSPath\\Batch.exe\"\n        Add-MpPreference -ExclusionProcess \"$AOSPath\\xppc.exe\"\n        Add-MpPreference -ExclusionProcess \"$AOSPath\\LabelC.exe\"\n        # add SQLServer\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files\\Microsoft SQL Server\\130\\LocalDB\\Binn\\sqlservr.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files\\Microsoft SQL Server\\150\\LocalDB\\Binn\\sqlservr.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files\\Microsoft SQL Server\\MSSQL13.MSSQLSERVER\\MSSQL\\Binn\\sqlservr.exe\"\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files\\Microsoft SQL Server\\MSSQL15.MSSQLSERVER\\MSSQL\\Binn\\sqlservr.exe\"\n\t\t# add IIS and IISExpress\n\t\tAdd-MpPreference -ExclusionProcess \"C:\\Windows\\System32\\inetsrv\\w3wp.exe\"\n\t\tAdd-MpPreference -ExclusionProcess \"C:\\Program Files\\IIS Express\\iisexpress.exe\"\n        # add Git\n        Add-MpPreference -ExclusionProcess \"C:\\Program Files\\Git\\cmd\\git.exe\"\n\n        #Compile kicks off the defender. Exclude base path to AOS helps on that.\n        Add-MpPreference -ExclusionPath $AOSServicePath\n\n        # cache folders\n        Add-MpPreference -ExclusionPath \"C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\"\n        Add-MpPreference -ExclusionPath \"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\"\n        Add-MpPreference -ExclusionPath \"C:\\Program Files (x86)\\Microsoft Visual Studio\"\n        Add-MpPreference -ExclusionPath \"C:\\Program Files\\Microsoft Visual Studio\"\n        Add-MpPreference -ExclusionPath \"C:\\Windows\\assembly\"\n        Add-MpPreference -ExclusionPath \"C:\\Windows\\Microsoft.NET\"\n        Add-MpPreference -ExclusionPath \"C:\\Program Files (x86)\\MSBuild\"\n        Add-MpPreference -ExclusionPath \"C:\\Program Files\\dotnet\"\n        Add-MpPreference -ExclusionPath \"C:\\Program Files (x86)\\Microsoft SDKs\"\n        Add-MpPreference -ExclusionPath \"C:\\Program Files\\Microsoft SDKs\"\n        Add-MpPreference -ExclusionPath \"C:\\Program Files (x86)\\Common Files\\Microsoft Shared\\MSEnv\"\n        Add-MpPreference -ExclusionPath \"C:\\Program Files (x86)\\Microsoft Office\"\n        \n        # Trick to get the exclusion path to work\n        Add-MpPreference -ExclusionPath $([System.Text.Encoding]::UTF8.GetString(([Convert]::FromBase64String(\"QzpcUHJvZ3JhbURhdGFcTWljcm9zb2Z0XFZpc3VhbFN0dWRpb1xQYWNrYWdlcw==\"))))\n\n        Add-MpPreference -ExclusionPath \"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\"\n        Add-MpPreference -ExclusionPath \"C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\Temporary ASP.NET Files\"\n        Add-MpPreference -ExclusionPath \"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\Temporary ASP.NET Files\"\n        Add-MpPreference -ExclusionPath \"C:\\Users\\Administrator\\AppData\\Local\\Microsoft\\VisualStudio\"\n        Add-MpPreference -ExclusionPath \"C:\\Users\\Administrator\\AppData\\Local\\Microsoft\\WebsiteCache\"\n        Add-MpPreference -ExclusionPath \"C:\\Users\\Administrator\\AppData\\Roaming\\Microsoft\\VisualStudio\"\n\t\tAdd-MpPreference -ExclusionPath \"$Env:USERPROFILE\\AppData\\Local\\Microsoft\\VisualStudio\"\n\t\tAdd-MpPreference -ExclusionPath \"$Env:USERPROFILE\\AppData\\Local\\Microsoft\\WebsiteCache\"\n\t\tAdd-MpPreference -ExclusionPath \"$Env:USERPROFILE\\AppData\\Roaming\\Microsoft\\VisualStudio\"\n\n        # Extensions\n        Add-MpPreference -ExclusionExtension \"md\"\n        Add-MpPreference -ExclusionExtension \"man\"\n        Add-MpPreference -ExclusionExtension \"xml\"\n        Add-MpPreference -ExclusionExtension \"xpp\"\n        Add-MpPreference -ExclusionExtension \"netmodule\"\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while configuring Windows Defender rules.\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/backup-d365devconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Backup the DynamicsDevConfig.xml file\n        \n    .DESCRIPTION\n        Will backup the DynamicsDevConfig.xml file located in the PackagesLocalDirectory\\Bin folder\n        \n    .PARAMETER OutputPath\n        Path to the folder where you want the DynamicsDevConfig.xml file to be persisted\n        \n        Default is: \"C:\\Temp\\d365fo.tools\\DevConfigBackup\"\n        \n    .PARAMETER Force\n        Instructs the cmdlet to overwrite the destination file if it already exists\n        \n    .EXAMPLE\n        PS C:\\> Backup-D365DevConfig\n        \n        Will locate the DynamicsDevConfig.xml file, and back it up.\n        It will look for the file in the PackagesLocalDirectory\\Bin folder. E.g. K:\\AosService\\PackagesLocalDirectory\\Bin\\DynamicsDevConfig.xml.\n        It will save the file to the default location: \"C:\\Temp\\d365fo.tools\\DevConfigBackup\".\n        \n        A result set example:\n        \n        Filename              LastModified         File\n        --------              ------------         ----\n        DynamicsDevConfig.xml 6/29/2021 7:31:04 PM C:\\temp\\d365fo.tools\\DevConfigBackup\\DynamicsDevConfig.xml\n        \n    .EXAMPLE\n        PS C:\\> Backup-D365DevConfig -Force\n        \n        Will locate the DynamicsDevConfig.xml file, back it up, and overwrite if a previous backup file exists.\n        It will look for the file in the PackagesLocalDirectory\\Bin folder. E.g. K:\\AosService\\PackagesLocalDirectory\\Bin\\DynamicsDevConfig.xml.\n        It will save the file to the default location: \"C:\\Temp\\d365fo.tools\\DevConfigBackup\".\n        It will overwrite any file named DynamicsDevConfig.xml in the destination folder.\n        \n        A result set example:\n        \n        Filename              LastModified         File\n        --------              ------------         ----\n        DynamicsDevConfig.xml 6/29/2021 7:31:04 PM C:\\temp\\d365fo.tools\\DevConfigBackup\\DynamicsDevConfig.xml\n        \n    .NOTES\n        Tags: Web Server, IIS, IIS Express, Development\n        \n        Author: Sander Holvoet (@smholvoet)\n        \n#>\nfunction Backup-D365DevConfig {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [string] $OutputPath = $(Join-Path $Script:DefaultTempPath \"DevConfigBackup\"),\n\n        [switch] $Force\n    )\n\n    begin {\n        if (-not (Test-PathExists -Path $OutputPath -Type Container -Create)) { return }\n\n        $File = $(Join-Path -Path (Join-Path -Path $Script:PackageDirectory -ChildPath \"bin\") -ChildPath $Script:DevConfig)\n    }\n    \n    process {\n\n        if (-not (Test-PathExists -Path $File -Type Leaf)) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        Backup-File -File $File -DestinationPath $OutputPath -Force:$Force\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/backup-d365metadatadir.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Create a backup of the Metadata directory\n        \n    .DESCRIPTION\n        Creates a backup of all the files and folders from the Metadata directory\n        \n    .PARAMETER MetaDataDir\n        Path to the Metadata directory\n        \n        Default value is the PackagesLocalDirectory\n        \n    .PARAMETER BackupDir\n        Path where you want the backup to be place\n        \n    .EXAMPLE\n        PS C:\\> Backup-D365MetaDataDir\n        \n        This will backup the PackagesLocalDirectory and create an PackagesLocalDirectory_backup next to it\n        \n    .NOTES\n        Tags: PackagesLocalDirectory, MetaData, MetaDataDir, MeteDataDirectory, Backup, Development\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Backup-D365MetaDataDir {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )]\n        [string] $MetaDataDir = \"$Script:MetaDataDir\",\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )]\n        [string] $BackupDir = \"$($Script:MetaDataDir)_backup\"\n        \n    )\n\n    if (!(Test-Path -Path $MetaDataDir -Type Container)) {\n        Write-PSFMessage -Level Host -Message \"The <c='em'>$MetaDataDir</c> path wasn't found. Please ensure the path <c='em'>exists </c> and you have enough <c='em'>permission/c> to access the directory.\"\n        Stop-PSFFunction -Message \"Stopping because the path is missing.\"\n        return\n    }\n\n    Invoke-TimeSignal -Start\n\n    $Params = @($MetaDataDir, $BackupDir, \"/MT:4\", \"/E\", \"/NFL\",\n        \"/NDL\", \"/NJH\", \"/NC\", \"/NS\", \"/NP\")\n\n    #! We should consider to redirect the standard output & error like this: https://stackoverflow.com/questions/8761888/capturing-standard-out-and-error-with-start-process\n    #Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly\n    Start-Process -FilePath \"Robocopy.exe\" -ArgumentList $Params -NoNewWindow -Wait\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/backup-d365runbook.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Backup a runbook file\n        \n    .DESCRIPTION\n        Backup a runbook file for you to persist it for later analysis\n        \n    .PARAMETER File\n        Path to the file you want to backup\n        \n    .PARAMETER DestinationPath\n        Path to the folder where you want the backup file to be placed\n        \n    .PARAMETER Force\n        Instructs the cmdlet to overwrite the destination file if it already exists\n        \n    .EXAMPLE\n        PS C:\\> Backup-D365Runbook -File \"C:\\DynamicsAX\\InstallationRecords\\Runbooks\\Runbook_20190327.xml\"\n        \n        This will backup the \"C:\\DynamicsAX\\InstallationRecords\\Runbooks\\Runbook_20190327.xml\".\n        The default destination folder is used, \"c:\\temp\\d365fo.tools\\runbookbackups\\\".\n        \n    .EXAMPLE\n        PS C:\\> Backup-D365Runbook -File \"C:\\DynamicsAX\\InstallationRecords\\Runbooks\\Runbook_20190327.xml\" -Force\n        \n        This will backup the \"C:\\DynamicsAX\\InstallationRecords\\Runbooks\\Runbook_20190327.xml\".\n        The default destination folder is used, \"c:\\temp\\d365fo.tools\\runbookbackups\\\".\n        If the file already exists in the destination folder, it will be overwritten.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Runbook | Backup-D365Runbook\n        \n        This will backup all runbook files found with the \"Get-D365Runbook\" cmdlet.\n        The default destination folder is used, \"c:\\temp\\d365fo.tools\\runbookbackups\\\".\n        \n    .NOTES\n        Tags: Runbook, Backup, Analysis\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Backup-D365Runbook {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]\n        [Alias('Path')]\n        [string] $File,\n\n        [string] $DestinationPath = $(Join-Path $Script:DefaultTempPath \"RunbookBackups\"),\n\n        [switch] $Force\n    )\n\n    begin {\n        if (-not (Test-PathExists -Path $DestinationPath -Type Container -Create)) { return }\n    }\n    \n    process {\n\n        if (-not (Test-PathExists -Path $File -Type Leaf)) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        Backup-File -File $File -DestinationPath $DestinationPath -Force:$Force\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/backup-d365webconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Backup the web.config file\n        \n    .DESCRIPTION\n        Will backup the web.config file located in the AOS / IIS folder\n        \n    .PARAMETER OutputPath\n        Path to the folder where you want the web.config file to be persisted\n        \n        Default is: \"C:\\Temp\\d365fo.tools\\WebConfigBackup\"\n        \n    .PARAMETER Force\n        Instructs the cmdlet to overwrite the destination file if it already exists\n        \n    .EXAMPLE\n        PS C:\\> Backup-D365WebConfig\n        \n        Will locate the web.config file, and back it up.\n        It will look for the file in the AOS / IIS folder. E.g. K:\\AosService\\WebRoot\\web.config.\n        It will save the file to the default location: \"C:\\Temp\\d365fo.tools\\WebConfigBackup\".\n        \n        A result set example:\n        \n        Filename   LastModified         File\n        --------   ------------         ----\n        web.config 6/29/2021 7:31:04 PM C:\\temp\\d365fo.tools\\WebConfigBackup\\web.config\n        \n    .EXAMPLE\n        PS C:\\> Backup-D365WebConfig -Force\n        \n        Will locate the web.config file, back it up, and overwrite if a previous backup file exists.\n        It will look for the file in the AOS / IIS folder. E.g. K:\\AosService\\WebRoot\\web.config.\n        It will save the file to the default location: \"C:\\Temp\\d365fo.tools\\WebConfigBackup\".\n        It will overwrite any file named web.config in the destination folder.\n        \n        A result set example:\n        \n        Filename   LastModified         File\n        --------   ------------         ----\n        web.config 6/29/2021 7:31:04 PM C:\\temp\\d365fo.tools\\WebConfigBackup\\web.config\n        \n    .NOTES\n        Tags: DEV, Tier2, DB, Database, Debug, JIT, LCS, Azure DB\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Backup-D365WebConfig {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [string] $OutputPath = $(Join-Path $Script:DefaultTempPath \"WebConfigBackup\"),\n\n        [switch] $Force\n    )\n\n    begin {\n        if (-not (Test-PathExists -Path $OutputPath -Type Container -Create)) { return }\n\n        $File = $(Join-Path -Path $Script:AOSPath -ChildPath $Script:WebConfig)\n    }\n    \n    process {\n\n        if (-not (Test-PathExists -Path $File -Type Leaf)) { return }\n        \n        if (Test-PSFFunctionInterrupt) { return }\n        \n        Backup-File -File $File -DestinationPath $OutputPath -Force:$Force\n\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/backup-d365wifconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Backup the wif.config file\n        \n    .DESCRIPTION\n        Will backup the wif.config file located in the AOS / IIS folder\n        \n    .PARAMETER OutputPath\n        Path to the folder where you want the web.config file to be persisted\n        \n        Default is: \"C:\\Temp\\d365fo.tools\\WifConfigBackup\"\n        \n    .PARAMETER Force\n        Instructs the cmdlet to overwrite the destination file if it already exists\n        \n    .EXAMPLE\n        PS C:\\> Backup-D365WifConfig\n        \n        Will locate the wif.config file, and back it up.\n        It will look for the file in the AOS / IIS folder. E.g. K:\\AosService\\WebRoot\\wif.config.\n        It will save the file to the default location: \"C:\\Temp\\d365fo.tools\\WifConfigBackup\".\n        \n        A result set example:\n        \n        Filename   LastModified         File\n        --------   ------------         ----\n        wif.config 6/29/2021 7:31:04 PM C:\\temp\\d365fo.tools\\WifConfigBackup\\wif.config\n        \n    .EXAMPLE\n        PS C:\\> Backup-D365WifConfig -Force\n        \n        Will locate the wif.config file, back it up, and overwrite if a previous backup file exists.\n        It will look for the file in the AOS / IIS folder. E.g. K:\\AosService\\WebRoot\\wif.config.\n        It will save the file to the default location: \"C:\\Temp\\d365fo.tools\\WifConfigBackup\".\n        It will overwrite any file named wif.config in the destination folder.\n        \n        A result set example:\n        \n        Filename   LastModified         File\n        --------   ------------         ----\n        wif.config 6/29/2021 7:31:04 PM C:\\temp\\d365fo.tools\\WifConfigBackup\\wif.config\n        \n    .NOTES\n        Author: Florian Hopfner (@FH-Inway)\n        \n#>\nfunction Backup-D365WifConfig {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [string] $OutputPath = $(Join-Path $Script:DefaultTempPath \"WifConfigBackup\"),\n\n        [switch] $Force\n    )\n\n    begin {\n        if (-not (Test-PathExists -Path $OutputPath -Type Container -Create)) { return }\n\n        $File = $(Join-Path -Path $Script:AOSPath -ChildPath $Script:WifConfig)\n    }\n    \n    process {\n\n        if (-not (Test-PathExists -Path $File -Type Leaf)) { return }\n        \n        if (Test-PSFFunctionInterrupt) { return }\n        \n        Backup-File -File $File -DestinationPath $OutputPath -Force:$Force\n\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/clear-d365activebroadcastmessageconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Clear the active broadcast message config\n        \n    .DESCRIPTION\n        Clear the active broadcast message config from the configuration store\n        \n    .PARAMETER Temporary\n        Instruct the cmdlet to only temporarily clear the active broadcast message configuration in the configuration store\n        \n    .EXAMPLE\n        PS C:\\> Clear-D365ActiveBroadcastMessageConfig\n        \n        This will clear the active broadcast message configuration from the configuration store.\n        \n    .NOTES\n        Tags: Servicing, Broadcast, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n    .LINK\n        Add-D365BroadcastMessageConfig\n        \n    .LINK\n        Get-D365ActiveBroadcastMessageConfig\n        \n    .LINK\n        Get-D365BroadcastMessageConfig\n        \n    .LINK\n        Remove-D365BroadcastMessageConfig\n        \n    .LINK\n        Send-D365BroadcastMessage\n        \n    .LINK\n        Set-D365ActiveBroadcastMessageConfig\n#>\n\nfunction Clear-D365ActiveBroadcastMessageConfig {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [switch] $Temporary\n    )\n\n    $configurationName = \"d365fo.tools.active.broadcast.message.config.name\"\n    \n    Reset-PSFConfig -FullName $configurationName\n\n    if (-not $Temporary) { Register-PSFConfig -FullName $configurationName -Scope UserDefault }\n}"
  },
  {
    "path": "d365fo.tools/functions/clear-d365bacpacobject.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Clear out sql objects from inside the bacpac/dacpac or zip file\n        \n    .DESCRIPTION\n        Remove a set of sql objects from inside a bacpac/dacpac or zip file, before restoring it into your SQL Server / Azure SQL DB\n        \n        It will open the file as a zip archive, locate the desired sql object and remove it, so when importing the bacpac the object will not be created\n        \n        The default behavior is that you get a copy of the file, where the desired sql objects are removed\n        \n    .PARAMETER Path\n        Path to the bacpac/dacpac or zip file that you want to work against\n        \n    .PARAMETER Name\n        Name of the sql object that you want to remove\n        \n        Supports an array of names\n        \n        If a schema name isn't supplied as part of the table name, the cmdlet will prefix it with \"dbo.\"\n        \n        Some sql objects are 3 part named, which will require that you fill them in with brackets E.g. [dbo].[SalesTable].[CustomIndexName1]\n        - Index\n        - Constraints\n        \n    .PARAMETER ObjectType\n        Instruct the cmdlet, the type of object that you want to remove\n        \n        As we are manipulating the bacpac file, we can only handle 1 ObjectType per run\n        \n        If you want to remove SqlView and SqlIndex, you will have to run the cmdlet 1 time for SqlViews and 1 time for SqlIndex\n        \n        Supported types are:\n        \"SqlView\", \"SqlTable\", \"SqlIndex\", \"SqlCheckConstraint\"\n        \n    .PARAMETER OutputPath\n        Path to where you want the updated bacpac/dacpac or zip file to be saved\n        \n    .PARAMETER ClearFromSource\n        Instruct the cmdlet to delete sql objects directly from the source file\n        \n        It will save disk space and time, because it doesn't have to create a copy of the bacpac file, before deleting sql objects from it\n        \n    .EXAMPLE\n        PS C:\\> Clear-D365BacpacObject -Path \"C:\\Temp\\AxDB.bacpac\" -ObjectType SqlView -Name \"View2\" -OutputPath \"C:\\Temp\\AXBD_Cleaned.bacpac\"\n        \n        This will remove the SqlView \"View2\" from inside the bacpac file.\n        \n        It uses \"C:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\n        It uses \"View2\" as the name of the object to delete.\n        It uses \"C:\\Temp\\AXBD_Cleaned.bacpac\" as the OutputPath to where it will store the updated bacpac file.\n        \n    .EXAMPLE\n        PS C:\\> Clear-D365BacpacObject -Path \"C:\\Temp\\AxDB.bacpac\" -ObjectType SqlView -Name \"dbo.View1\",\"View2\" -OutputPath \"C:\\Temp\\AXBD_Cleaned.bacpac\"\n        \n        This will remove the SqlView(s) \"dbo.View1\" and \"View2\" from inside the bacpac file.\n        \n        It uses \"C:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\n        It uses \"dbo.View1\",\"View2\" as the names of objects to delete.\n        It uses \"C:\\Temp\\AXBD_Cleaned.bacpac\" as the OutputPath to where it will store the updated bacpac file.\n        \n    .EXAMPLE\n        PS C:\\> Clear-D365BacpacObject -Path \"C:\\Temp\\AxDB.bacpac\" -ObjectType SqlIndex -Name \"[dbo].[SalesTable].[CustomIndexName1]\" -ClearFromSource\n        \n        This will remove the SqlIndex \"CustomIndexName1\" from the dbo.SalesTable table from inside the bacpac file.\n        \n        It uses \"C:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\n        It uses \"[dbo].[SalesTable].[CustomIndexName1]\" as the name of the object to delete.\n        \n        Caution:\n        It will remove from the source \"C:\\Temp\\AxDB.bacpac\" directly. So if the original file is important for further processing, please consider the risks carefully.\n        \n    .NOTES\n        It will NOT fail, if it can't find any object with the specified name\n        \n#>\nfunction Clear-D365BacpacObject {\n    [CmdletBinding(DefaultParameterSetName = \"Copy\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')]\n    param (\n        [Parameter(Mandatory = $true)]\n        [Alias('File')]\n        [Alias('BacpacFile')]\n        [string] $Path,\n\n        [Parameter(Mandatory = $true)]\n        [Alias(\"ObjectName\")]\n        [string[]] $Name,\n\n        [ValidateSet(\"SqlView\", \"SqlTable\", \"SqlIndex\", \"SqlCheckConstraint\")]\n        [string] $ObjectType,\n\n        [Parameter(Mandatory = $true, ParameterSetName = \"Copy\")]\n        [string] $OutputPath,\n\n        [Parameter(Mandatory = $true, ParameterSetName = \"Keep\")]\n        [switch] $ClearFromSource\n    )\n    \n    if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n    $compressPath = \"\"\n\n    if ($ClearFromSource) {\n        $compressPath = $Path\n    }\n    else {\n        $compressPath = $OutputPath\n\n        if (-not (Test-PathExists -Path $compressPath -Type Leaf -ShouldNotExist)) {\n            Write-PSFMessage -Level Host -Message \"The <c='em'>$compressPath</c> already exists. Consider changing the <c='em'>OutputPath</c> or <c='em'>delete</c> the <c='em'>$compressPath</c> file.\"\n            return\n        }\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        Write-PSFMessage -Level Verbose -Message \"Copying the file from '$Path' to '$compressPath'\"\n        Copy-Item -Path $Path -Destination $compressPath\n        Write-PSFMessage -Level Verbose -Message \"Copying was completed.\"\n    }\n        \n    Write-PSFMessage -Level Verbose -Message \"Opening the file '$compressPath'.\"\n    $file = [System.IO.File]::Open($compressPath, [System.IO.FileMode]::Open)\n    $zipArch = [System.IO.Compression.ZipArchive]::new($file, [System.IO.Compression.ZipArchiveMode]::Update)\n    Write-PSFMessage -Level Verbose -Message \"File '$compressPath' was read succesfully.\"\n\n    if (-not $zipArch) {\n        $messageString = \"Unable to open the file <c='em'>$compressPath</c>.\"\n        Write-PSFMessage -Level Host -Message $messageString\n        Stop-PSFFunction -Message \"Stopping because the file couldn't be opened.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', '')))\n        return\n    }\n\n    $pathWorkDirectory = \"$([System.IO.Path]::GetTempPath())d365fo.tools\\$([System.Guid]::NewGuid().Guid)\"\n        \n    #Make sure the work path is created and available\n    New-Item -Path $pathWorkDirectory -ItemType Directory -Force -ErrorAction Ignore > $null\n\n    if (Test-PSFFunctionInterrupt) { return }\n    \n    Write-PSFMessage -Level Verbose -Message \"Building the regex patterns to look for in the model.xml file.\"\n    \n    # Build the array of regex patterns that we are looking for\n    # Has to be the same type\n    $searchCol = @(\n        foreach ($item in $Name) {\n            $fullObjectName = \"\"\n\n            if (-not ($item -like \"*.*\")) {\n                $fullObjectName = \"[dbo].[$item]\"\n            }\n            elseif ($item -like \"*.*\" -and (-not ($item -match '\\[.*?\\]\\.\\[.*?\\]') )) {\n                #Throw error name format isn't as expected\n                Throw\n            }\n            else {\n                $fullObjectName = $item\n            }\n\n            $regexName = $fullObjectName.Replace(\"[\", \"\\[\").Replace(\"]\", \"\\]\").Replace(\".\", \"\\.\")\n\n            '<Element Type=\"{0}\" Name=\"{1}\">' -f $ObjectType, $regexName\n        })\n\n    # The model files defines all objects that will be created when importing the bacpac file\n    $model = $zipArch.GetEntry(\"model.xml\")\n\n    Write-PSFMessage -Level Verbose -Message \"Extracting local model.xml file.\"\n\n    # We will have a local \"model.raw.xml\" file to read from\n    $pathModelRaw = Join-Path -Path $pathWorkDirectory -ChildPath \"model.raw.xml\"\n    [System.IO.Compression.ZipFileExtensions]::ExtractToFile($model, $pathModelRaw)\n\n    # We will have a local \"model.xml\" where we persist the changes to\n    $pathModelWorking = Join-Path -Path $pathWorkDirectory -ChildPath \"model.xml\"\n\n    # The Origin.xml file is a manifest file, with a checksum value for the model.xml file inside the bacpac\n    # Removing a single character from the model.xml file, will invalidate the checksum stored inside the Origin.xml\n    $origin = $zipArch.GetEntry(\"Origin.xml\")\n        \n    Write-PSFMessage -Level Verbose -Message \"Extracting local Origin.xml file.\"\n\n    # We will have a local \"Origin.raw.xml\" file to read from\n    $pathOriginRaw = Join-Path -Path $pathWorkDirectory -ChildPath \"Origin.raw.xml\"\n    [System.IO.Compression.ZipFileExtensions]::ExtractToFile($origin, $pathOriginRaw)\n\n    # We will have a local \"Origin.xml\" where we persist the changes to\n    $pathOriginWorking = Join-Path -Path $pathWorkDirectory -ChildPath \"Origin.xml\"\n\n    # The model file is a very large XML file, reading that into a DOM object will slow down the operation\n    # We will be reading the file line-by-line\n    $reader = [System.IO.StreamReader]::new($pathModelRaw)\n    $writer = [System.IO.StreamWriter]::new($pathModelWorking)\n\n    # We need to know when to skip lines and at what indent to stop skipping lines\n    $skipLine = $false\n    $skipIdent = -1\n\n    Write-PSFMessage -Level Verbose -Message \"Starting the analysis of the model.xml file.\"\n\n    :nextLine while ( -not $reader.EndOfStream) {\n        $tmp = $reader.ReadLine()\n\n        if ($skipLine) {\n            # SkipLine indicates that we found the object that we want to remove\n            # We need to search for the very first NEXT instance of \"</Element>\"\n\n            if ($tmp -match \"</Element>\") {\n                # We found a \"</Element>\", but there are several child elements\n\n                if ($skipIdent -eq $tmp.IndexOf(\"<\")) {\n                    Write-PSFMessage -Level Verbose -Message \"Skipping lines disabled. Correct close element found.\"\n\n                    # The identication signals that we found the right \"</Element>\"\n\n                    # Resitting the search signal/variables\n                    $skipLine = $false\n                    $skipIdent = -1\n                    continue nextLine\n                }\n            }\n\n            # We need to move forward with reading the file\n            continue nextLine\n        }\n\n        foreach ($regex in $searchCol) {\n            # searchCol contains ALL regex patterns that we want to remove from the model file\n            # This is done to increase performance, as we only read the file onces, but validates each line multiple times\n\n            if (($tmp -match $regex)) {\n                Write-PSFMessage -Level Verbose -Message \"Regex: $regex had a match. Skipping lines until close element found.\"\n\n                # A match indicates that we found the next object that we want to remove\n\n                # Setting the signal/variables - identication helps later to match to the correct \"</Element>\"\n                $skipIdent = $tmp.IndexOf(\"<\")\n                $skipLine = $true\n                continue nextLine\n            }\n        }\n\n        # If skipLine and no regex was hit, we need to line in the updated model.xml file\n        $writer.WriteLine($tmp)\n    }\n    \n    # This concludes the entire update on the model.xml file\n    $reader.Close()\n    $writer.Flush()\n    $writer.Close()\n\n    Write-PSFMessage -Level Verbose -Message \"Calculating hash value (checksum) for the updated model.xml file.\"\n\n    # The model file will be checksum validated when running an import of it\n    # We need to handle that\n    $hashValue = Get-FileHash -Path $pathModelWorking -Algorithm SHA256 | Select-Object -ExpandProperty Hash\n\n    # Loading the Origin.xml into memory\n    [xml]$xmlDoc = Get-Content -Path $pathOriginRaw\n\n    Write-PSFMessage -Level Verbose -Message \"Updating the hash value (checksum) inside the Origin.xml file.\"\n\n    # Updating the hash vaule (checksum) and saving it\n    $xmlDoc.DacOrigin.Checksums.Checksum.InnerText = $hashValue\n    $xmlDoc.Save($pathOriginWorking)\n\n    Write-PSFMessage -Level Verbose -Message \"Switching out the Origin.xml and model.xml files from inside the bacpac.\"\n\n    # We need to remove the model.xml and origin.xml from the bacpac (archive)\n    $model.Delete()\n    $origin.Delete()\n\n    [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zipArch, $pathModelWorking, \"model.xml\") > $null\n    [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zipArch, $pathOriginWorking, \"Origin.xml\") > $null\n\n    $res = @{ }\n    \n    if ($zipArch) {\n        $zipArch.Dispose()\n    }\n\n    if ($file) {\n        $file.Close()\n        $file.Dispose()\n    }\n\n    if (Test-PSFFunctionInterrupt) { return }\n    \n    $res.File = $compressPath\n    $res.Filename = $(Split-Path -Path $compressPath -Leaf)\n\n    [PSCustomObject]$res\n}"
  },
  {
    "path": "d365fo.tools/functions/clear-d365bacpactabledata.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Clear out data for a table inside the bacpac/dacpac or zip file\n        \n    .DESCRIPTION\n        Remove all data for a table inside a bacpac/dacpac or zip file, before restoring it into your SQL Server / Azure SQL DB\n        \n        It will open the file as a zip archive, locate the desired table and remove the data that otherwise would have been loaded\n        \n        The default behavior is that you get a copy of the file, where the desired data is removed\n        \n    .PARAMETER Path\n        Path to the bacpac/dacpac or zip file that you want to work against\n        \n    .PARAMETER Table\n        Name of the table that you want to delete the data for\n        \n        Supports an array of table names\n        \n        If a schema name isn't supplied as part of the table name, the cmdlet will prefix it with \"dbo.\"\n        \n        Supports wildcard searching e.g. \"Sales*\" will delete all \"dbo.Sales*\" tables in the bacpac file\n        \n    .PARAMETER OutputPath\n        Path to where you want the updated bacpac/dacpac or zip file to be saved\n        \n    .PARAMETER ClearFromSource\n        Instruct the cmdlet to delete tables directly from the source file\n        \n        It will save disk space and time, because it doesn't have to create a copy of the bacpac file, before deleting tables from it\n        \n    .EXAMPLE\n        PS C:\\> Clear-D365BacpacTableData -Path \"C:\\Temp\\AxDB.bacpac\" -Table \"BATCHJOBHISTORY\" -OutputPath \"C:\\Temp\\AXBD_Cleaned.bacpac\"\n        \n        This will remove the data from the BatchJobHistory table from inside the bacpac file.\n        \n        It uses \"C:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\n        It uses \"BATCHJOBHISTORY\" as the Table to delete data from.\n        It uses \"C:\\Temp\\AXBD_Cleaned.bacpac\" as the OutputPath to where it will store the updated bacpac file.\n        \n    .EXAMPLE\n        PS C:\\> Clear-D365BacpacTableData -Path \"C:\\Temp\\AxDB.bacpac\" -Table \"dbo.BATCHHISTORY\",\"BATCHJOBHISTORY\" -OutputPath \"C:\\Temp\\AXBD_Cleaned.bacpac\"\n        \n        This will remove the data from the dbo.BatchHistory and BatchJobHistory table from inside the bacpac file.\n        \n        It uses \"C:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\n        It uses \"dbo.BATCHHISTORY\",\"BATCHJOBHISTORY\" as the Table to delete data from.\n        It uses \"C:\\Temp\\AXBD_Cleaned.bacpac\" as the OutputPath to where it will store the updated bacpac file.\n        \n    .EXAMPLE\n        PS C:\\> Clear-D365BacpacTableData -Path \"C:\\Temp\\AxDB.bacpac\" -Table \"dbo.BATCHHISTORY\",\"BATCHJOBHISTORY\" -ClearFromSource\n        \n        This will remove the data from the dbo.BatchHistory and BatchJobHistory table from inside the bacpac file.\n        \n        It uses \"C:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\n        It uses \"dbo.BATCHHISTORY\",\"BATCHJOBHISTORY\" as the Table to delete data from.\n        \n        Caution:\n        It will remove from the source \"C:\\Temp\\AxDB.bacpac\" directly. So if the original file is important for further processing, please consider the risks carefully.\n        \n    .EXAMPLE\n        PS C:\\> Clear-D365BacpacTableData -Path \"C:\\Temp\\AxDB.bacpac\" -Table \"CustomTableNameThatDoesNotExists\",\"BATCHJOBHISTORY\" -OutputPath \"C:\\Temp\\AXBD_Cleaned.bacpac\" -ErrorAction SilentlyContinue\n        \n        This will remove the data from the BatchJobHistory table from inside the bacpac file.\n        \n        It uses \"C:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\n        It uses \"CustomTableNameThatDoesNotExists\",\"BATCHJOBHISTORY\" as the Table to delete data from.\n        It respects the respects the ErrorAction \"SilentlyContinue\", and will continue removing tables from the bacpac file, even when some tables are missing.\n        It uses \"C:\\Temp\\AXBD_Cleaned.bacpac\" as the OutputPath to where it will store the updated bacpac file.\n        \n    .NOTES\n        Tags: Bacpac, Servicing, Data, Deletion, SqlPackage\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Clear-D365BacpacTableData {\n    [Alias(\"Clear-D365TableDataFromBacpac\")]\n    [CmdletBinding(DefaultParameterSetName = \"Copy\")]\n    param (\n        [Parameter(Mandatory = $true)]\n        [Alias('File')]\n        [Alias('BacpacFile')]\n        [string] $Path,\n\n        [Parameter(Mandatory = $true)]\n        [Alias(\"TableName\")]\n        [string[]] $Table,\n\n        [Parameter(Mandatory = $true, ParameterSetName = \"Copy\")]\n        [string] $OutputPath,\n\n        [Parameter(Mandatory = $true, ParameterSetName = \"Keep\")]\n        [switch] $ClearFromSource\n    )\n    \n    begin {\n        if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n        $compressPath = \"\"\n\n        if ($ClearFromSource) {\n            $compressPath = $Path\n        }\n        else {\n            $compressPath = $OutputPath\n\n            if (-not (Test-PathExists -Path $compressPath -Type Leaf -ShouldNotExist)) {\n                Write-PSFMessage -Level Host -Message \"The <c='em'>$compressPath</c> already exists. Consider changing the <c='em'>OutputPath</c> or <c='em'>delete</c> the <c='em'>$compressPath</c> file.\"\n                return\n            }\n\n            if (Test-PSFFunctionInterrupt) { return }\n\n            Write-PSFMessage -Level Verbose -Message \"Copying the file from '$Path' to '$compressPath'\"\n            Copy-Item -Path $Path -Destination $compressPath\n            Write-PSFMessage -Level Verbose -Message \"Copying was completed.\"\n        }\n        \n        Write-PSFMessage -Level Verbose -Message \"Opening the file '$compressPath'.\"\n        $file = [System.IO.File]::Open($compressPath, [System.IO.FileMode]::Open)\n        $zipArch = [System.IO.Compression.ZipArchive]::new($file, [System.IO.Compression.ZipArchiveMode]::Update)\n        Write-PSFMessage -Level Verbose -Message \"File '$compressPath' was read succesfully.\"\n\n        if (-not $zipArch) {\n            $messageString = \"Unable to open the file <c='em'>$compressPath</c>.\"\n            Write-PSFMessage -Level Host -Message $messageString\n            Stop-PSFFunction -Message \"Stopping because the file couldn't be opened.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', '')))\n            return\n        }\n    }\n    \n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        foreach ($item in $Table) {\n            $fullTableName = \"\"\n\n            if (-not ($item -like \"*.*\")) {\n                $fullTableName = \"dbo.$item\"\n            }\n            else {\n                $fullTableName = $item\n            }\n\n            Write-PSFMessage -Level Verbose -Message \"Looking for $fullTableName.\"\n            $entries = @($zipArch.Entries | Where-Object Fullname -like \"Data/$fullTableName/*\")\n\n            if ($entries.Count -lt 1) {\n                Write-PSFMessage -Level Host -Message \"The <c='em'>$item</c> wasn't found. Please ensure that the <c='em'>schema</c> or <c='em'>name</c> is correct.\"\n                \n                $parms = @{Message = \"Stopping because table was not present.\" }\n                if ($ErrorActionPreference -eq \"SilentlyContinue\") {\n                    $parms.WarningAction = $ErrorActionPreference\n                    $parms.ErrorAction = $null\n                }\n\n                Stop-PSFFunction @parms\n            }\n            else {\n                for ($i = 0; $i -lt $entries.Count; $i++) {\n                    Write-PSFMessage -Level Verbose -Message \"Removing $($entries[$i]) from the file.\"\n\n                    $entries[$i].delete()\n                }\n            }\n        }\n    }\n    \n    end {\n        Write-PSFMessage -Level Verbose -Message \"Search completed.\"\n\n        $res = @{ }\n\n        if ($zipArch) {\n            Write-PSFMessage -Level Verbose -Message \"Closing and saving the file.\"\n            $zipArch.Dispose()\n        }\n\n        if ($file) {\n            $file.Close()\n            $file.Dispose()\n        }\n        \n        if (Test-PSFFunctionInterrupt) { return }\n\n        $res.File = $compressPath\n        $res.Filename = $(Split-Path -Path $compressPath -Leaf)\n\n        [PSCustomObject]$res\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/clear-d365monitordata.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Clear the monitoring data from a Dynamics 365 for Finance & Operations machine\n        \n    .DESCRIPTION\n        Clear the monitoring data that is filling up the service drive on a Dynamics 365 for Finance & Operations\n        \n    .PARAMETER Path\n        The path to where the monitoring data is located\n        \n        The default value is the \"ServiceDrive\" (j:\\ | k:\\) and the \\MonAgentData\\SingleAgent\\Tables folder structure\n        \n    .EXAMPLE\n        PS C:\\> Clear-D365MonitorData\n        \n        This will delete all the files that are located in the default path on the machine.\n        Some files might be locked by a process, but the cmdlet will attemp to delete all files.\n        \n    .NOTES\n        Tags: Monitor, MonitorData, MonitorAgent, CleanUp, Servicing\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Clear-D365MonitorData {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Position = 1, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]\n        [string] $Path = (Join-Path $script:ServiceDrive \"\\MonAgentData\\SingleAgent\\Tables\")\n    )\n    \n    process {\n        Get-ChildItem -Path $Path | Remove-Item -Force -ErrorAction SilentlyContinue\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/clear-d365tempdbtables.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Cleanup TempDB tables in Microsoft Dynamics 365 for Finance and Operations environment\n        \n    .DESCRIPTION\n        This will cleanup X days of TempDB tables\n        \n        The reason behind this process is that sp_updatestats takes significantly longer depending on the number of TempDB tables in the system\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER Days\n        Temp tables older than this Days input will be dropped\n        \n        The default value is 7 (days)\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Clear-D365TempDbTables -Days 7\n        \n        This will cleanup old tempdb tables.\n        It will use 7 as the Days parameter.\n        \n        The remaining parameters will use their default values, which are provided by the tools.\n        \n    .LINK\n        https://msdyn365fo.wordpress.com/2019/12/18/cleanup-tempdb-tables-in-a-msdyn365fo-sandbox-environment/\n        \n    .LINK\n        https://github.com/PaulHeisterkamp/d365fo.blog/blob/master/Tools/SQL/DropTempDBTables.sql\n        \n    .NOTES\n        \n        Author: Alex Kwitny (@AlexOnDAX)\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        This cmdlet is based on the findings from Paul Heisterkamp (@braul)\n        \n        See his blog for more info:\n        https://msdyn365fo.wordpress.com/2019/12/18/cleanup-tempdb-tables-in-a-msdyn365fo-sandbox-environment/\n#>\n\nfunction Clear-D365TempDbTables {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    param\n    (\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [int] $Days = 7,\n        \n        [switch] $EnableException\n    )\n    \n    Invoke-TimeSignal -Start\n\n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n    \n    $Params = @{DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd; TrustedConnection = $UseTrustedConnection;\n    }\n\n    $sqlCommand = Get-SQLCommand @Params\n\n    $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\clear-d365tempdbtables.sql\") -join [Environment]::NewLine\n    $commandText = $commandText.Replace('@Days', $Days)\n\n    $sqlCommand.CommandText = $commandText\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n\n        $null = $sqlCommand.ExecuteNonQuery()\n    }\n    catch {\n        $messageString = \"Something went wrong while working against the database.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand)\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/convertto-d365dacpac.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Convert bacpac file to dacpac\n        \n    .DESCRIPTION\n        Convert bacpac file to dacpac\n        \n        It will extract the origin.xml file from the file, and set the <ContainsExportedData>false</ContainsExportedData> for the file to be valid to be used as a dacpac file\n        \n    .PARAMETER Path\n        Path to the bacpac file that you want to work against\n        \n        It can also be a zip file\n        \n    .EXAMPLE\n        PS C:\\> ConvertTo-D365Dacpac -Path \"C:\\Temp\\AxDB.bacpac\"\n        \n        This will convert the bacpac file into a dacpac file.\n        It will extract the origin.xml file, update it and apply it to the file.\n        It will rename the file into a dacpac.\n        \n        The source file will be manipulated, so be careful to have an extra copy of the file.\n        \n    .NOTES\n        Tags: Bacpac, Servicing, Data, SqlPackage, Dacpac, Table\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction ConvertTo-D365Dacpac {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [Alias('File')]\n        [Alias('BacpacFile')]\n        [string] $Path\n    )\n    \n    begin {\n    }\n\n    process {\n    }\n    \n    end {\n        if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        $fileName = [System.IO.Path]::GetFileNameWithoutExtension($Path)\n\n        $OutputPath = Join-Path -Path $([System.IO.Path]::GetTempPath()) -ChildPath \"Origin.xml\"\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        $file = [System.IO.File]::Open($Path, [System.IO.FileMode]::Open)\n\n        $zipArch = [System.IO.Compression.ZipArchive]::new($file, [System.IO.Compression.ZipArchiveMode]::Update)\n        \n        $originEntry = $zipArch.GetEntry(\"Origin.xml\")\n\n        if (-not $originEntry) {\n            $messageString = \"Unable to find the <c='em'>Origin.xml</c> file inside the archive. It would indicate the <c='em'>$Path</c> isn't a valid bacpac or dacpac.\"\n            Write-PSFMessage -Level Host -Message $messageString\n            Stop-PSFFunction -Message \"Stopping because Origin.xml wasn't found.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', '')))\n        }\n        \n        if (Test-PSFFunctionInterrupt) { return }\n\n        [System.IO.Compression.ZipFileExtensions]::ExtractToFile($originEntry, $OutputPath, $true)\n        \n        $originEntry.delete()\n        \n        $content = Get-Content -Path $OutputPath -Raw\n\n        $content = $content -replace \"<ContainsExportedData>true</ContainsExportedData>\", \"<ContainsExportedData>false</ContainsExportedData>\"\n\n        $content | Out-File -FilePath $OutputPath -Encoding utf8 -Force\n\n        [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zipArch, $OutputPath, \"Origin.xml\") > $null\n            \n        if ($zipArch) {\n            $zipArch.Dispose()\n        }\n\n        if ($file) {\n            $file.Close()\n            $file.Dispose()\n        }\n\n        Rename-Item -Path $Path -NewName \"$($fileName).dacpac\"\n\n        [PSCustomObject]@{\n            File     = $Path.Replace(\"bacpac\", \"dacpac\")\n            Filename = \"$($fileName).dacpac\"\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/disable-d365exception.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Disables throwing of exceptions\n        \n    .DESCRIPTION\n        Restore the default exception behavior of the module to not support throwing exceptions\n        \n        Useful when the default behavior was changed with Enable-D365Exception and the default behavior should be restored\n        \n    .EXAMPLE\n        PS C:\\>Disable-D365Exception\n        \n        This will restore the default behavior of the module to not support throwing exceptions.\n        \n    .NOTES\n        Tags: Exception, Exceptions, Warning, Warnings\n        \n        Author: Florian Hopfner (@FH-Inway)\n        \n    .LINK\n        Enable-D365Exception\n#>\n\nfunction Disable-D365Exception {\n    [CmdletBinding()]\n    param ()\n\n    Write-PSFMessage -Level Verbose -Message \"Disabling exception across the entire module.\" -Target $configurationValue\n\n    Set-PSFFeature -Name 'PSFramework.InheritEnableException' -Value $false -ModuleName \"D365fo.tools\"\n    Set-PSFFeature -Name 'PSFramework.InheritEnableException' -Value $false -ModuleName \"PSOAuthHelper\"\n    $PSDefaultParameterValues['*:EnableException'] = $false\n}"
  },
  {
    "path": "d365fo.tools/functions/disable-d365flight.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Used to disable a flight\n        \n    .DESCRIPTION\n        Provides a method for disabling a flight in D365FO.\n        \n    .PARAMETER FlightName\n        Name of the flight to disable\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .EXAMPLE\n        PS C:\\> Disable-D365Flight -FlightName DMFEnableAllCompanyExport\n        \n        Disables the flight DMFEnableAllCompanyExport\n        \n    .LINK\n        https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages#features-flighted-in-data-management-and-enabling-flighted-features\n        \n    .NOTES\n        Tags: Flight, Flighting\n        \n        Author: Frank Hüther (@FrankHuether)\n        \n        The DataAccess.FlightingServiceCatalogID must already be set in the web.config file.\n        \n        At no circumstances can this cmdlet be used to enable a flight in a PROD environment.\n#>\nfunction Disable-D365Flight {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true, Position = 1)]\n        [String] $FlightName,\n\n        [Parameter(Mandatory = $false, Position = 2)]\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Mandatory = $false, Position = 3)]\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false, Position = 4)]\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false, Position = 5)]\n        [string] $SqlPwd = $Script:DatabaseUserPassword\n    )\n\n    try {\n        $WebConfigFile = join-Path -path $Script:AOSPath $Script:WebConfig\n        Write-PSFMessage -Level Verbose -Message \"Retrieve the FlightingServiceCatalogID\" -Target $WebConfigFile\n\n        $FlightServiceNode = Select-Xml -XPath \"/configuration/appSettings/add[@key='DataAccess.FlightingServiceCatalogID']/@value\" -Path $WebConfigFile\n        $FlightServiceId = $FlightServiceNode.Node.Value\n    \n        Write-PSFMessage -Level Verbose -Message \"FlightingServiceCatalogID: $FlightServiceId\" -Target $WebConfigFile\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while reading from the web.config file\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n\n    if ($null -eq $FlightServiceId) {\n        Write-PSFMessage -Level Host -Message \"The DataAccess.FlightingServiceCatalogID setting must be set in the web.config file. See https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages#features-flighted-in-data-management-and-enabling-flighted-features for details\"\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n\n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n    $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd\n    }\n\n    $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n    $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\disable-flight.sql\") -join [Environment]::NewLine\n\n    try {\n        $sqlCommand.Connection.Open()\n\n        Write-PSFMessage -Level Verbose -Message \"Disabling flight: $FlightName\"\n\n        $null = $sqlCommand.Parameters.Add(\"@FlightName\", $FlightName)\n        $null = $sqlCommand.Parameters.Add(\"@FlightServiceId\", $FlightServiceId)\n\n        Write-PSFMessage -Level Verbose -Message \"Disable the flight in database\"\n\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $null = $sqlCommand.ExecuteNonQuery()\n    \n        Write-PSFMessage -Level Verbose -Message \"Flight $FlightName disabled with service ID $FlightServiceId\"\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n        $sqlCommand.Dispose()\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/disable-d365iispreload.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Disables IIS Preload for the AOSService application pool and website.\n        \n    .DESCRIPTION\n        Reverts IIS Preload settings for the AOSService application:\n        - Sets Application Pool Start Mode to OnDemand\n        - Sets Idle Time-out to 0 (default)\n        - Disables Preload on the AOSService website\n        - Sets doAppInitAfterRestart to false (if Application Initialization is installed)\n        - Restores previous IIS Preload configuration from backup if available\n        - Restores or removes the initializationPage property as appropriate\n        - Uninstalls IIS Application Initialization feature if it was not installed in the backup\n        \n    .EXAMPLE\n        PS C:\\> Disable-D365IISPreload\n        \n        Disables IIS Preload for the AOSService application pool and website, restoring previous settings from backup if available.\n        \n    .NOTES\n        Author: Florian Hopfner (FH-Inway)\n        Based on Denis Trunin's article \"Enable IIS Preload to Speed Up Restart After X++ Compile\" (https://www.linkedin.com/pulse/enable-iis-preload-speed-up-restart-after-x-compile-denis-trunin-86j5c)\n        Written with GitHub Copilot GPT-4.1, mostly in agent mode. See commits for prompts.\n        \n    .LINK\n        Get-D365IISPreload\n        \n    .LINK\n        Enable-D365IISPreload\n#>\nfunction Disable-D365IISPreload {\n    [CmdletBinding()]\n    param ()\n\n    if (-not (Get-Module -ListAvailable -Name WebAdministration)) {\n        Write-PSFMessage -Level Warning -Message \"The 'WebAdministration' module is not installed. Please install it with: Install-WindowsFeature -Name Web-WebServer -IncludeManagementTools or Install-Module -Name WebAdministration -Scope CurrentUser\"\n        return\n    }\n\n    Import-Module WebAdministration -ErrorAction Stop\n\n    $appPool = \"AOSService\"\n    $site = \"AOSService\"\n\n    # Set default values first\n    $startMode = 'OnDemand'\n    $idleTimeout = [TimeSpan]::Zero\n    $preloadEnabled = $false\n    $doAppInitAfterRestart = 'False'\n    $preloadPage = $null\n\n    # Try to restore previous IIS Preload configuration from backup if available\n    $backupDir = Join-Path $Script:DefaultTempPath \"IISConfigBackup\"\n    $backupFile = $null\n    if (Test-Path $backupDir) {\n        $backupFiles = Get-ChildItem -Path $backupDir -Filter 'IISPreloadConfig.*.json' | Sort-Object LastWriteTime -Descending\n        if ($backupFiles) {\n            $backupFile = $backupFiles[0].FullName\n        }\n    }\n    if ($backupFile) {\n        Write-PSFMessage -Level Host -Message \"Restoring IIS Preload configuration from backup: $backupFile\"\n        $preloadConfig = Get-Content $backupFile | ConvertFrom-Json\n        if ($preloadConfig.StartMode) { $startMode = $preloadConfig.StartMode }\n        if ($preloadConfig.IdleTimeout) { $idleTimeout = $preloadConfig.IdleTimeout }\n        if ($null -ne $preloadConfig.PreloadEnabled) { $preloadEnabled = $preloadConfig.PreloadEnabled }\n        if ($preloadConfig.DoAppInitAfterRestart) { $doAppInitAfterRestart = $preloadConfig.DoAppInitAfterRestart }\n        if ($preloadConfig.PreloadPage) { $preloadPage = $preloadConfig.PreloadPage }\n        # Uninstall IIS Application Initialization feature if it was not installed in the backup\n        if ($preloadConfig.IISApplicationInitFeature -eq 'Not installed') {\n            Write-PSFMessage -Level Host -Message \"Uninstalling IIS Application Initialization feature (Web-AppInit) as per backup state.\"\n            try {\n                Uninstall-WindowsFeature -Name Web-AppInit -Confirm:$false | Out-Null\n            } catch {\n                Write-PSFMessage -Level Warning -Message \"Failed to uninstall IIS Application Initialization feature. $_\"\n            }\n        }\n    }\n\n    # Set Application Pool Start Mode and Idle Time-out\n    $setAppPoolStartModeParams = @{\n        Path  = \"IIS:\\AppPools\\$appPool\"\n        Name  = 'startMode'\n        Value = $startMode\n    }\n    Write-PSFMessage -Level Verbose -Message \"Setting Application Pool '$appPool' startMode to '$startMode'\"\n    Set-ItemProperty @setAppPoolStartModeParams\n    $setAppPoolIdleTimeoutParams = @{\n        Path  = \"IIS:\\AppPools\\$appPool\"\n        Name  = 'processModel.idleTimeout'\n        Value = $idleTimeout\n    }\n    Write-PSFMessage -Level Verbose -Message \"Setting Application Pool '$appPool' idleTimeout to '$idleTimeout'\"\n    Set-ItemProperty @setAppPoolIdleTimeoutParams\n    $setSitePreloadParams = @{\n        Path  = \"IIS:\\Sites\\$site\"\n        Name  = 'applicationDefaults.preloadEnabled'\n        Value = $preloadEnabled\n    }\n    Write-PSFMessage -Level Verbose -Message \"Setting Site '$site' applicationDefaults.preloadEnabled to '$preloadEnabled'\"\n    Set-ItemProperty @setSitePreloadParams\n    try {\n        $setDoAppInitParams = @{\n            pspath      = \"MACHINE/WEBROOT/APPHOST/$site\"\n            filter      = 'system.webServer/applicationInitialization'\n            name        = 'doAppInitAfterRestart'\n            value       = $doAppInitAfterRestart\n            ErrorAction = 'Stop'\n        }\n        Write-PSFMessage -Level Verbose -Message \"Setting Site '$site' doAppInitAfterRestart to '$doAppInitAfterRestart'\"\n        Set-WebConfigurationProperty @setDoAppInitParams\n    } catch {\n        Write-PSFMessage -Level Verbose -Message \"Application Initialization not installed or not available. Skipping doAppInitAfterRestart.\"\n    }\n\n    # Reset or remove initializationPage setting\n    $getInitPagesParams = @{\n        pspath      = 'MACHINE/WEBROOT/APPHOST'\n        filter      = 'system.webServer/applicationInitialization'\n        name        = '.'\n        location    = $site\n        ErrorAction = 'Stop'\n    }\n    $initPages = Get-WebConfigurationProperty @getInitPagesParams\n    if ($initPages -and $initPages.Collection -and $initPages.Collection.Count -gt 0) {\n        $currentPreloadPage = $initPages.Collection[0].initializationPage\n    }\n    if ($currentPreloadPage) {\n        if ($preloadPage -and $preloadPage -ne \"Not configured\" -and $preloadPage -ne \"Not available\") {\n            try {\n                Write-PSFMessage -Level Verbose -Message \"Setting Site '$site' initializationPage to '$preloadPage'\"\n                $setInitPageParams = @{\n                    pspath      = \"MACHINE/WEBROOT/APPHOST/$site\"\n                    filter      = 'system.webServer/applicationInitialization'\n                    name        = '.'\n                    value       = @{ initializationPage = $preloadPage }\n                    AtElement   = @{ initializationPage = $currentPreloadPage }\n                    ErrorAction = 'Stop'\n                }\n                Set-WebConfigurationProperty @setInitPageParams\n            } catch {\n                Write-PSFMessage -Level Verbose -Message \"Preload page $preloadPage cannot be set. Application Initialization may not be installed or not available. Skipping initializationPage.\"\n            }\n        } else {\n            try {\n                Write-PSFMessage -Level Verbose -Message \"Removing initializationPage from Site '$site'\"\n                if ($currentPreloadPage) {\n                    $removeInitPageParams = @{\n                        pspath      = \"MACHINE/WEBROOT/APPHOST/$site\"\n                        filter      = 'system.webServer/applicationInitialization'\n                        name        = '.'\n                        AtElement   = @{ initializationPage = $currentPreloadPage }\n                        ErrorAction = 'Stop'\n                    }\n                    Remove-WebConfigurationProperty @removeInitPageParams\n                }\n            } catch {\n                Write-PSFMessage -Level Verbose -Message \"Failed to remove initializationPage from Site '$site'. It may not exist.\"\n            }\n        }\n    }\n    \n    Write-PSFMessage -Level Host -Message \"IIS Preload disabled for $site.\"\n\n    # Restart IIS service to apply changes\n    try {\n        Write-PSFMessage -Level Host -Message \"Restarting IIS service (W3SVC) to apply changes...\"\n        Restart-Service -Name 'W3SVC' -Force -ErrorAction Stop\n        Write-PSFMessage -Level Host -Message \"IIS service restarted successfully.\"\n    } catch {\n        Write-PSFMessage -Level Warning -Message \"Failed to restart IIS service (W3SVC): $_\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/disable-d365maintenancemode.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Sets the environment back into operating state\n        \n    .DESCRIPTION\n        Sets the Dynamics 365 environment back into operating / running state after it has been in maintenance mode.\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable or SQL script and the needed parameters based on your selection\n        \n    .EXAMPLE\n        PS C:\\> Disable-D365MaintenanceMode\n        \n        On VHD based environments, this will execute the Microsoft.Dynamics.AX.Deployment.Setup.exe with the default values that was pulled from the environment and put the environment into the operate / running state. On cloud hosted environments, a SQL script is used instead.\n        \n    .EXAMPLE\n        PS C:\\> Disable-D365MaintenanceMode -ShowOriginalProgress\n        \n        On VHD based environments, this will execute the Microsoft.Dynamics.AX.Deployment.Setup.exe with the default values that was pulled from the environment and put the environment into the operate / running state. On cloud hosted environments, a SQL script is used instead.\n        The output from stopping the services will be written to the console / host.\n        The output from the \"deployment\" process will be written to the console / host.\n        The output from starting the services will be written to the console / host.\n        \n    .NOTES\n        Tags: MaintenanceMode, Maintenance, License, Configuration, Servicing\n        \n        Author: Mötz Jensen (@splaxi)\n        Author: Tommy Skaue (@skaue)\n        \n        On VHD based environments with administrator privileges:\n        The cmdlet wraps the execution of Microsoft.Dynamics.AX.Deployment.Setup.exe and parses the parameters needed.\n        \n        Without administrator privileges or on cloud hosted environments:\n        Will stop all services, execute a SQL script and start all services.\n        \n    .LINK\n        Enable-D365MaintenanceMode\n        \n    .LINK\n        Get-D365MaintenanceMode\n        \n#>\nfunction Disable-D365MaintenanceMode {\n    [CmdletBinding()]\n    param (\n        [string] $MetaDataDir = \"$Script:MetaDataDir\",\n\n        [string] $BinDir = \"$Script:BinDir\",\n\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\MaintenanceMode\"),\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly\n\n    )\n    \n    if ((Get-Process -Name \"devenv\" -ErrorAction SilentlyContinue).Count -gt 0) {\n        Write-PSFMessage -Level Host -Message \"It seems that you have a <c='em'>Visual Studio</c> running. Please <c='em'>exit</c> Visual Studio and run the cmdlet again.\"\n        Stop-PSFFunction -Message \"Stopping because of running Visual Studio.\"\n        return\n    }\n\n    if (-not $OutputCommandOnly) {\n        Stop-D365Environment -All -ShowOriginalProgress:$ShowOriginalProgress | Format-Table\n    }\n\n    if (-not ($Script:IsAdminRuntime) -or ($Script:EnvironmentType -eq [EnvironmentType]::AzureHostedTier1)) {\n        Write-PSFMessage -Level Verbose -Message \"Setting Maintenance Mode without using executable (which requires local admin).\"\n        \n        $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n        $Params = @{\n            DatabaseServer = $DatabaseServer\n            DatabaseName   = $DatabaseName\n            SqlUser        = $SqlUser\n            SqlPwd         = $SqlPwd\n        }\n\n        if ($OutputCommandOnly) {\n            $scriptContent = Get-content -Path $(\"$script:ModuleRoot\\internal\\sql\\disable-maintenancemode.sql\") -Raw\n            Write-PSFMessage -Level Host -Message \"It seems that you want the command, but you're running in a non-elevated console. Will output the SQL script that is avaiable.\"\n            Write-PSFMessage -Level Host -Message \"$scriptContent\"\n        }\n        else {\n            Invoke-D365SqlScript @Params -FilePath $(\"$script:ModuleRoot\\internal\\sql\\disable-maintenancemode.sql\") -TrustedConnection $UseTrustedConnection\n        }\n    }\n    else {\n        Write-PSFMessage -Level Verbose -Message \"Setting Maintenance Mode using executable.\"\n\n        $executable = Join-Path -Path $BinDir -ChildPath \"bin\\Microsoft.Dynamics.AX.Deployment.Setup.exe\"\n\n        if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { return }\n        if (-not (Test-PathExists -Path $executable -Type Leaf)) { return }\n\n        $params = @(\"-isemulated\", \"true\",\n            \"-sqluser\", \"$SqlUser\",\n            \"-sqlpwd\", \"$SqlPwd\",\n            \"-sqlserver\", \"$DatabaseServer\",\n            \"-sqldatabase\", \"$DatabaseName\",\n            \"-metadatadir\", \"$MetaDataDir\",\n            \"-bindir\", \"$BinDir\",\n            \"-setupmode\", \"maintenancemode\",\n            \"-isinmaintenancemode\", \"false\")\n\n        Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n    }\n\n    if ($OutputCommandOnly) { return }\n\n    Start-D365Environment -All -ShowOriginalProgress:$ShowOriginalProgress | Format-Table\n\n}"
  },
  {
    "path": "d365fo.tools/functions/disable-d365sqlchangetracking.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Disable Change Tracking for the environment\n        \n    .DESCRIPTION\n        Disables the SQL Server Change Tracking for the environments database and all tables inside the database\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Disable-D365SqlChangeTracking\n        \n        This will disable the Change Tracking on the Sql Server.\n        \n    .NOTES\n        Tags: MaintenanceMode, Maintenance, License, Configuration, Servicing\n        \n        Author: Mötz Jensen (@splaxi)\n#>\nfunction Disable-D365SqlChangeTracking {\n    [CmdletBinding()]\n    param (\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [switch] $EnableException\n    )\n\n    Invoke-TimeSignal -Start\n\n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n    \n    $Params = @{DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd; TrustedConnection = $UseTrustedConnection;\n    }\n\n    $sqlCommand = Get-SQLCommand @Params\n\n    $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\disable-changetracking.sql\") -join [Environment]::NewLine\n    $commandText = $commandText.Replace('@DATABASENAME', $DatabaseName)\n\n    $sqlCommand.CommandText = $commandText\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n\n        $null = $sqlCommand.ExecuteNonQuery()\n    }\n    catch {\n        $messageString = \"Something went wrong while working against the database.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand)\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n    }\n\n    Invoke-TimeSignal -End\n\n}"
  },
  {
    "path": "d365fo.tools/functions/disable-d365user.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Disables the user in D365FO\n        \n    .DESCRIPTION\n        Sets the enabled to 0 in the userinfo table.\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER Email\n        The search string to select which user(s) should be disabled.\n        \n        The parameter supports wildcards. E.g. -Email \"*@contoso.com*\"\n        \n    .EXAMPLE\n        PS C:\\> Disable-D365User\n        \n        This will Disable all users for the environment\n        \n    .EXAMPLE\n        PS C:\\> Disable-D365User -Email \"claire@contoso.com\"\n        \n        This will Disable the user with the email address \"claire@contoso.com\"\n        \n    .EXAMPLE\n        PS C:\\> Disable-D365User -Email \"*contoso.com\"\n        \n        This will Disable all users that matches the search \"*contoso.com\" in their email address\n        \n    .NOTES\n        Tags: User, Users, Security, Configuration, Permission\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Disable-D365User {\n\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $false, Position = 1)]\n        [string]$DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Mandatory = $false, Position = 2)]\n        [string]$DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false, Position = 3)]\n        [string]$SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false, Position = 4)]\n        [string]$SqlPwd = $Script:DatabaseUserPassword,\n\n        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 5)]\n        [string]$Email = \"*\"\n\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n\n        $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n        $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n            SqlUser = $SqlUser; SqlPwd = $SqlPwd\n        }\n\n        $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n\n        try {\n            $sqlCommand.Connection.Open()\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\disable-user.sql\") -join [Environment]::NewLine\n    \n        $null = $sqlCommand.Parameters.AddWithValue('@Email', $Email.Replace(\"*\", \"%\"))\n\n        try {\n            Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n            $reader = $sqlCommand.ExecuteReader()\n            $NumAffected = 0\n\n            while ($reader.Read() -eq $true) {\n                Write-PSFMessage -Level Verbose -Message \"User $($reader.GetString(0)), $($reader.GetString(1)), $($reader.GetString(2)) Updated\"\n                $NumAffected++\n            }\n\n            $reader.Close()\n            Write-PSFMessage -Level Verbose -Message \"Users updated : $NumAffected\"\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n        finally {\n            $reader.close()\n            $sqlCommand.Parameters.Clear()\n        }\n    }\n\n    end {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/enable-d365exception.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Enable exceptions to be thrown\n        \n    .DESCRIPTION\n        Change the default exception behavior of the module to support throwing exceptions\n        \n        Useful when the module is used in an automated fashion, like inside Azure DevOps pipelines and large PowerShell scripts\n        \n    .EXAMPLE\n        PS C:\\>Enable-D365Exception\n        \n        This will for the rest of the current PowerShell session make sure that exceptions will be thrown.\n        \n    .NOTES\n        Tags: Exception, Exceptions, Warning, Warnings\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n    .LINK\n        Disable-D365Exception\n#>\n\nfunction Enable-D365Exception {\n    [CmdletBinding()]\n    param ()\n\n    Write-PSFMessage -Level Verbose -Message \"Enabling exception across the entire module.\" -Target $configurationValue\n\n    Set-PSFFeature -Name 'PSFramework.InheritEnableException' -Value $true -ModuleName \"D365fo.tools\"\n    Set-PSFFeature -Name 'PSFramework.InheritEnableException' -Value $true -ModuleName \"PSOAuthHelper\"\n    $PSDefaultParameterValues['*:EnableException'] = $true\n}"
  },
  {
    "path": "d365fo.tools/functions/enable-d365flight.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Used to enable a flight\n        \n    .DESCRIPTION\n        Provides a method for enabling a flight in D365FO.\n        \n    .PARAMETER FlightName\n        Name of the flight to enable\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .EXAMPLE\n        PS C:\\> Enable-D365Flight -FlightName DMFEnableAllCompanyExport\n        \n        Enables the flight DMFEnableAllCompanyExport\n        \n    .NOTES\n        Tags: Flight, Flighting\n        \n        Author: Frank Hüther (@FrankHuether)\n        \n        The DataAccess.FlightingServiceCatalogID must already be set in the web.config file.\n        https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages#features-flighted-in-data-management-and-enabling-flighted-features\n        \n        At no circumstances can this cmdlet be used to enable a flight in a PROD environment.\n#>\nfunction Enable-D365Flight {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true, Position = 1)]\n        [String] $FlightName,\n\n        [Parameter(Mandatory = $false, Position = 2)]\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Mandatory = $false, Position = 3)]\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false, Position = 4)]\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false, Position = 5)]\n        [string] $SqlPwd = $Script:DatabaseUserPassword\n    )\n\n    try {\n        $WebConfigFile = join-Path -path $Script:AOSPath $Script:WebConfig\n        Write-PSFMessage -Level Verbose -Message \"Retrieve the FlightingServiceCatalogID\" -Target $WebConfigFile\n\n        $FlightServiceNode = Select-Xml -XPath \"/configuration/appSettings/add[@key='DataAccess.FlightingServiceCatalogID']/@value\" -Path $WebConfigFile\n        $FlightServiceId = $FlightServiceNode.Node.Value\n    \n        Write-PSFMessage -Level Verbose -Message \"FlightingServiceCatalogID: $FlightServiceId\" -Target $WebConfigFile\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while reading from the web.config file\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n\n    if ($null -eq $FlightServiceId) {\n        Write-PSFMessage -Level Host -Message \"The DataAccess.FlightingServiceCatalogID setting must be set in the web.config file. See https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages#features-flighted-in-data-management-and-enabling-flighted-features for details\"\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n\n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n    $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd\n    }\n\n    $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n    $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\enable-flight.sql\") -join [Environment]::NewLine\n\n    try {\n        $sqlCommand.Connection.Open()\n\n        Write-PSFMessage -Level Verbose -Message \"Enabling flight: $FlightName\"\n\n        $null = $sqlCommand.Parameters.Add(\"@FlightName\", $FlightName)\n        $null = $sqlCommand.Parameters.Add(\"@FlightServiceId\", $FlightServiceId)\n\n        Write-PSFMessage -Level Verbose -Message \"Enable the flight in database\"\n\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $null = $sqlCommand.ExecuteNonQuery()\n    \n        Write-PSFMessage -Level Verbose -Message \"Flight $FlightName enabled with service ID $FlightServiceId\"\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n        $sqlCommand.Dispose()\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/enable-d365iispreload.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Enables IIS Preload for the AOSService application pool and website.\n        \n    .DESCRIPTION\n        Configures IIS to preload the AOSService application, improving startup time after X++ compile.\n        - Sets Application Pool Start Mode to AlwaysRunning\n        - Sets Idle Time-out to 0\n        - Enables Preload on the AOSService website\n        - Sets doAppInitAfterRestart to true (if Application Initialization is installed)\n        - Optionally sets the initializationPage to a custom base URL\n        \n    .PARAMETER BaseUrl\n        The base URL to use for the initializationPage setting in IIS Application Initialization.\n        If not provided, the function will attempt to determine the base URL automatically using Get-D365Url.\n        Example: https://usnconeboxax1aos.cloud.onebox.dynamics.com\n        \n    .EXAMPLE\n        PS C:\\> Enable-D365IISPreload\n        \n        This will enable IIS Preload and set the initializationPage using the automatically detected base URL.\n        \n    .EXAMPLE\n        PS C:\\> Enable-D365IISPreload -BaseUrl \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\"\n        \n        This will enable IIS Preload and set the initializationPage to https://usnconeboxax1aos.cloud.onebox.dynamics.com/?mi=DefaultDashboard\n        \n    .NOTES\n        Author: Florian Hopfner (FH-Inway)\n        Based on Denis Trunin's article \"Enable IIS Preload to Speed Up Restart After X++ Compile\" (https://www.linkedin.com/pulse/enable-iis-preload-speed-up-restart-after-x-compile-denis-trunin-86j5c)\n        Written with GitHub Copilot GPT-4.1, mostly in agent mode. See commits for prompts.\n        \n    .LINK\n        Get-D365IISPreload\n        \n    .LINK\n        Disable-D365IISPreload\n#>\nfunction Enable-D365IISPreload {\n    [CmdletBinding()]\n    param (\n        [string]$BaseUrl = \"\"\n    )\n\n    \n    if (-not (Get-Module -ListAvailable -Name WebAdministration)) {\n        Write-PSFMessage -Level Warning -Message \"The 'WebAdministration' module is not installed. Please install it with: Install-WindowsFeature -Name Web-WebServer -IncludeManagementTools or Install-Module -Name WebAdministration -Scope CurrentUser\"\n        return\n    }\n    \n    Import-Module WebAdministration -ErrorAction Stop\n    \n    # Backup IIS Preload configuration before making changes\n    $backupDir = Join-Path $Script:DefaultTempPath \"IISConfigBackup\"\n    if (-not (Test-Path $backupDir)) {\n        New-Item -Path $backupDir -ItemType Directory | Out-Null\n    }\n    $timestamp = Get-Date -Format 'yyyyMMdd_HHmmss'\n    $iisConfigBackupFile = Join-Path $backupDir (\"IISPreloadConfig.$timestamp.json\")\n    $preloadConfig = Get-D365IISPreload | ConvertTo-Json -Depth 5\n    $preloadConfig | Out-File -FilePath $iisConfigBackupFile -Encoding UTF8\n    Write-PSFMessage -Level Host -Message \"IIS Preload configuration backed up to $iisConfigBackupFile\"\n    \n    # Ensure IIS Application Initialization feature is installed\n    $iisAppInitFeature = Get-WindowsFeature -Name Web-AppInit -ErrorAction SilentlyContinue\n    if (-not ($iisAppInitFeature -and $iisAppInitFeature.Installed)) {\n        Write-PSFMessage -Level Host -Message \"IIS Application Initialization (Web-AppInit) feature is not installed. Installing...\"\n        Install-WindowsFeature -Name Web-AppInit -IncludeAllSubFeature -IncludeManagementTools -ErrorAction Stop | Out-Null\n        Write-PSFMessage -Level Host -Message \"IIS Application Initialization feature installed.\"\n    }\n\n    $appPool = \"AOSService\"\n    $site = \"AOSService\"\n\n    # Set Application Pool to AlwaysRunning and Idle Time-out to 0\n    $setAppPoolStartModeParams = @{\n        Path  = \"IIS:\\AppPools\\$appPool\"\n        Name  = 'startMode'\n        Value = 'AlwaysRunning'\n    }\n    Write-PSFMessage -Level Verbose -Message \"Setting Application Pool '$appPool' startMode to 'AlwaysRunning'\"\n    Set-ItemProperty @setAppPoolStartModeParams\n    $setAppPoolIdleTimeoutParams = @{\n        Path  = \"IIS:\\AppPools\\$appPool\"\n        Name  = 'processModel.idleTimeout'\n        Value = ([TimeSpan]::Zero)\n    }\n    Write-PSFMessage -Level Verbose -Message \"Setting Application Pool '$appPool' idleTimeout to '0'\"\n    Set-ItemProperty @setAppPoolIdleTimeoutParams\n\n    # Enable Preload on the website\n    $setSitePreloadParams = @{\n        Path  = \"IIS:\\Sites\\$site\"\n        Name  = 'applicationDefaults.preloadEnabled'\n        Value = $true\n    }\n    Write-PSFMessage -Level Verbose -Message \"Setting Site '$site' applicationDefaults.preloadEnabled to 'True'\"\n    Set-ItemProperty @setSitePreloadParams\n\n    if (-not $BaseUrl) {\n        try {\n            $baseUrlObj = Get-D365Url\n            if ($baseUrlObj -and $baseUrlObj.Url) {\n                $BaseUrl = $baseUrlObj.Url.TrimEnd('/')\n            }\n        } catch {\n            Write-PSFMessage -Level Verbose -Message \"Could not determine base URL using Get-D365Url. Defaulting to root.\"\n            $BaseUrl = \"\"\n        }\n    }\n\n    # Set the initializationPage for application initialization\n    try {\n        $initPage = if ($BaseUrl) { \"$BaseUrl/?mi=DefaultDashboard\" } else { \"/?mi=DefaultDashboard\" }\n        Write-PSFMessage -Level Verbose -Message \"Setting Site '$site' initializationPage to '$initPage'\"\n        $addInitPageParams = @{\n            pspath      = \"MACHINE/WEBROOT/APPHOST/$site\"\n            filter      = 'system.webServer/applicationInitialization'\n            name        = '.'\n            value       = @{ initializationPage = $initPage }\n            ErrorAction = 'Stop'\n        }\n        Add-WebConfigurationProperty @addInitPageParams\n    } catch {\n        Write-PSFMessage -Level Verbose -Message \"Preload page $initPage cannot be set. Application Initialization may not be installed or not available. Skipping initializationPage.\"\n    }\n\n    # Try to set doAppInitAfterRestart if Application Initialization is installed\n    try {\n        $setDoAppInitParams = @{\n            pspath      = \"MACHINE/WEBROOT/APPHOST/$site\"\n            filter      = 'system.webServer/applicationInitialization'\n            name        = 'doAppInitAfterRestart'\n            value       = 'True'\n            ErrorAction = 'Stop'\n        }\n        Write-PSFMessage -Level Verbose -Message \"Setting Site '$site' doAppInitAfterRestart to 'True'\"\n        Set-WebConfigurationProperty @setDoAppInitParams\n    } catch {\n        Write-PSFMessage -Level Verbose -Message \"doAppInitAfterRestart cannot be set. Application Initialization may not be installed or not available. Skipping doAppInitAfterRestart.\"\n    }\n\n    Write-PSFMessage -Level Host -Message \"IIS Preload enabled for $site.\"\n\n    # Restart IIS service to apply changes\n    try {\n        Write-PSFMessage -Level Host -Message \"Restarting IIS service (W3SVC) to apply preload settings...\"\n        Restart-Service -Name 'W3SVC' -Force -ErrorAction Stop\n        Write-PSFMessage -Level Host -Message \"IIS service restarted successfully.\"\n    } catch {\n        Write-PSFMessage -Level Warning -Message \"Failed to restart IIS service (W3SVC): $_\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/enable-d365maintenancemode.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Sets the environment into maintenance mode\n        \n    .DESCRIPTION\n        Sets the Dynamics 365 environment into maintenance mode to enable the user to update the license configuration\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable or SQL script and the needed parameters based on your selection\n        \n    .EXAMPLE\n        PS C:\\> Enable-D365MaintenanceMode\n        \n        On VHD based environments, this will execute the Microsoft.Dynamics.AX.Deployment.Setup.exe with the default values that was pulled from the environment and put the environment into the maintenance mode. On cloud hosted environments, a SQL script is used instead.\n        \n    .EXAMPLE\n        PS C:\\> Enable-D365MaintenanceMode -ShowOriginalProgress\n        \n        On VHD based environments, this will execute the Microsoft.Dynamics.AX.Deployment.Setup.exe with the default values that was pulled from the environment and put the environment into the maintenance mode. On cloud hosted environments, a SQL script is used instead.\n        The output from stopping the services will be written to the console / host.\n        The output from the \"deployment\" process will be written to the console / host.\n        The output from starting the services will be written to the console / host.\n        \n    .NOTES\n        Tags: MaintenanceMode, Maintenance, License, Configuration, Servicing\n        \n        Author: Mötz Jensen (@splaxi)\n        Author: Tommy Skaue (@skaue)\n        \n        On VHD based environments with administrator privileges:\n        The cmdlet wraps the execution of Microsoft.Dynamics.AX.Deployment.Setup.exe and parses the parameters needed.\n        \n        Without administrator privileges or on cloud hosted environments:\n        Will stop all services, execute a SQL script and starts the AOS service (other services are not needed during maintenance mode).\n        \n    .LINK\n        Get-D365MaintenanceMode\n        \n    .LINK\n        Disable-D365MaintenanceMode\n#>\nfunction Enable-D365MaintenanceMode {\n    [CmdletBinding()]\n    param (\n        [string] $MetaDataDir = \"$Script:MetaDataDir\",\n\n        [string] $BinDir = \"$Script:BinDir\",\n\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\MaintenanceMode\"),\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly\n    )\n\n    if ((Get-Process -Name \"devenv\" -ErrorAction SilentlyContinue).Count -gt 0) {\n        Write-PSFMessage -Level Host -Message \"It seems that you have a <c='em'>Visual Studio</c> running. Please <c='em'>exit</c> Visual Studio and run the cmdlet again.\"\n        Stop-PSFFunction -Message \"Stopping because of running Visual Studio.\"\n        return\n    }\n    \n    if (-not $OutputCommandOnly) {\n        Stop-D365Environment -All -ShowOriginalProgress:$ShowOriginalProgress | Format-Table\n    }\n\n    if (-not ($Script:IsAdminRuntime) -or ($Script:EnvironmentType -eq [EnvironmentType]::AzureHostedTier1)) {\n        Write-PSFMessage -Level Verbose -Message \"Setting Maintenance Mode without using executable (which requires local admin).\"\n\n        $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n        $Params = @{\n            DatabaseServer = $DatabaseServer\n            DatabaseName   = $DatabaseName\n            SqlUser        = $SqlUser\n            SqlPwd         = $SqlPwd\n        }\n\n        if ($OutputCommandOnly) {\n            $scriptContent = Get-content -Path $(\"$script:ModuleRoot\\internal\\sql\\enable-maintenancemode.sql\") -Raw\n            Write-PSFMessage -Level Host -Message \"It seems that you want the command, but you're running in a non-elevated console. Will output the SQL script that is avaiable.\"\n            Write-PSFMessage -Level Host -Message \"$scriptContent\"\n        }\n        else {\n            Invoke-D365SqlScript @Params -FilePath $(\"$script:ModuleRoot\\internal\\sql\\enable-maintenancemode.sql\") -TrustedConnection $UseTrustedConnection\n        }\n    }\n    else {\n        Write-PSFMessage -Level Verbose -Message \"Setting Maintenance Mode using executable.\"\n\n        $executable = Join-Path -Path $BinDir -ChildPath \"bin\\Microsoft.Dynamics.AX.Deployment.Setup.exe\"\n\n        if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { return }\n        if (-not (Test-PathExists -Path $executable -Type Leaf)) { return }\n\n        $params = @(\"-isemulated\", \"true\",\n            \"-sqluser\", \"$SqlUser\",\n            \"-sqlpwd\", \"$SqlPwd\",\n            \"-sqlserver\", \"$DatabaseServer\",\n            \"-sqldatabase\", \"$DatabaseName\",\n            \"-metadatadir\", \"$MetaDataDir\",\n            \"-bindir\", \"$BinDir\",\n            \"-setupmode\", \"maintenancemode\",\n            \"-isinmaintenancemode\", \"true\")\n\n        Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n    }\n\n    if ($OutputCommandOnly) { return }\n    \n    Start-D365Environment -Aos -ShowOriginalProgress:$ShowOriginalProgress | Format-Table\n}"
  },
  {
    "path": "d365fo.tools/functions/enable-d365sqlchangetracking.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Enable Change Tracking for the environment\n        \n    .DESCRIPTION\n        Enable the SQL Server Change Tracking for the environments database\n        \n        It is a requirement for the Data Entities refresh to be able to complete correctly\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Enable-D365SqlChangeTracking\n        \n        This will enable the Change Tracking on the Sql Server.\n        \n    .NOTES\n        Tags: MaintenanceMode, Maintenance, License, Configuration, Servicing\n        \n        Author: Mötz Jensen (@splaxi)\n#>\nfunction Enable-D365SqlChangeTracking {\n    [CmdletBinding()]\n    param (\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [switch] $EnableException\n    )\n\n    Invoke-TimeSignal -Start\n\n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n    \n    $Params = @{DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd; TrustedConnection = $UseTrustedConnection;\n    }\n\n    $sqlCommand = Get-SQLCommand @Params\n\n    $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\enable-changetracking.sql\") -join [Environment]::NewLine\n    $commandText = $commandText.Replace('@DATABASENAME', $DatabaseName)\n\n    $sqlCommand.CommandText = $commandText\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n\n        $null = $sqlCommand.ExecuteNonQuery()\n    }\n    catch {\n        $messageString = \"Something went wrong while working against the database.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand)\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n    }\n\n    Invoke-TimeSignal -End\n\n}"
  },
  {
    "path": "d365fo.tools/functions/enable-d365user.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Enables the user in D365FO\n        \n    .DESCRIPTION\n        Sets the enabled to 1 in the userinfo table\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER Email\n        The search string to select which user(s) should be enabled\n        \n        The parameter supports wildcards. E.g. -Email \"*@contoso.com*\"\n        \n        Default value is \"*\" to update all users\n        \n    .EXAMPLE\n        PS C:\\> Enable-D365User\n        \n        This will enable all users for the environment\n        \n    .EXAMPLE\n        PS C:\\> Enable-D365User -Email \"claire@contoso.com\"\n        \n        This will enable the user with the email address \"claire@contoso.com\"\n        \n    .EXAMPLE\n        PS C:\\> Enable-D365User -Email \"*contoso.com\"\n        \n        This will enable all users that matches the search \"*contoso.com\" in their email address\n        \n    .NOTES\n        Tags: User, Users, Security, Configuration, Permission\n        \n        Author: Mötz Jensen\n        \n#>\nfunction Enable-D365User {\n\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $false, Position = 1)]\n        [string]$DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Mandatory = $false, Position = 2)]\n        [string]$DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false, Position = 3)]\n        [string]$SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false, Position = 4)]\n        [string]$SqlPwd = $Script:DatabaseUserPassword,\n\n        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 5)]\n        [string]$Email = \"*\"\n\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n\n        $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n        $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n            SqlUser = $SqlUser; SqlPwd = $SqlPwd\n        }\n\n        $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n\n        try {\n            $sqlCommand.Connection.Open()\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n\n        $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\enable-user.sql\") -join [Environment]::NewLine\n            \n        $null = $sqlCommand.Parameters.AddWithValue('@Email', $Email.Replace(\"*\", \"%\"))\n\n        try {\n            Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n            $reader = $sqlCommand.ExecuteReader()\n            $NumAffected = 0\n            while ($reader.Read() -eq $true) {\n                Write-PSFMessage -Level Verbose -Message \"User $($reader.GetString(0)), $($reader.GetString(1)), $($reader.GetString(2)) Updated\"\n                $NumAffected++\n            }\n\n            $reader.Close()\n            Write-PSFMessage -Level Verbose -Message \"Users updated : $NumAffected\"\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n        finally {\n            $reader.close()\n            $sqlCommand.Parameters.Clear()\n        }\n    }\n\n    end {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/export-d365bacpacmodelfile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Extract the \"model.xml\" from the bacpac file\n        \n    .DESCRIPTION\n        Extract the \"model.xml\" file from inside the bacpac file\n        \n        This can be used to update SQL Server options for how the SqlPackage.exe should import the bacpac file into your SQL Server / Azure SQL DB\n        \n    .PARAMETER Path\n        Path to the bacpac file that you want to work against\n        \n        It can also be a zip file\n        \n    .PARAMETER OutputPath\n        Path to where you want the updated bacpac file to be saved\n        \n        Default value is: \"c:\\temp\\d365fo.tools\"\n        \n    .PARAMETER Force\n        Switch to instruct the cmdlet to overwrite the \"model.xml\" specified in the OutputPath\n        \n    .EXAMPLE\n        PS C:\\> Export-D365BacpacModelFile -Path \"c:\\Temp\\AxDB.bacpac\"\n        \n        This will extract the \"model.xml\" file from inside the bacpac file.\n        \n        It uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\n        It uses the default value \"c:\\temp\\d365fo.tools\" as the OutputPath to where it will store the extracted \"bacpac.model.xml\" file.\n        \n    .EXAMPLE\n        PS C:\\> Export-D365BacpacModelFile -Path \"c:\\Temp\\AxDB.bacpac\" -OutputPath \"c:\\Temp\\model.xml\" -Force\n        \n        This will extract the \"model.xml\" file from inside the bacpac file.\n        \n        It uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\n        It uses \"c:\\Temp\\model.xml\" as the OutputPath to where it will store the extracted \"model.xml\" file.\n        \n        It will override the \"c:\\Temp\\model.xml\" if already present.\n        \n    .EXAMPLE\n        PS C:\\> Export-D365BacpacModelFile -Path \"c:\\Temp\\AxDB.bacpac\" | Get-D365BacpacSqlOptions\n        \n        This will display all the SQL Server options configured in the bacpac file.\n        First it will export the bacpac.model.xml from the \"c:\\Temp\\AxDB.bacpac\" file, using the Export-D365BacpacModelFile function.\n        The output from Export-D365BacpacModelFile will be piped into the Get-D365BacpacSqlOptions function.\n        \n    .NOTES\n        Tags: Bacpac, Servicing, Data, SqlPackage, Sql Server Options, Collation\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Export-D365BacpacModelFile {\n    [Alias(\"Get-D365ModelFileFromBacpac\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [Alias('File')]\n        [Alias('BacpacFile')]\n        [string] $Path,\n\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [switch] $Force\n    )\n    \n    begin {\n        if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        if ($OutputPath -eq $Script:DefaultTempPath) {\n            $OutputPath = Join-Path -Path $OutputPath -ChildPath \"bacpac.model.xml\"\n        }\n        \n        Test-PathExists -Path $(Split-Path -Path $OutputPath -Parent) -Type Container -Create > $null\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        if (-not $Force) {\n            if (-not (Test-PathExists -Path $OutputPath -Type Leaf -ShouldNotExist)) {\n                Write-PSFMessage -Level Host -Message \"The <c='em'>$OutputPath</c> already exists. Consider changing the <c='em'>OutputPath</c> or set the <c='em'>Force</c> parameter to overwrite the file.\"\n                Stop-PSFFunction -Message \"Stopping because output path was already present.\"\n                return\n            }\n        }\n\n        if (Test-PSFFunctionInterrupt) { return }\n    }\n    \n    end {\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        $file = [System.IO.File]::Open($Path, [System.IO.FileMode]::Open)\n\n        $zipArch = [System.IO.Compression.ZipArchive]::new($file)\n        \n        $modelEntry = $zipArch.GetEntry(\"model.xml\")\n\n        if (-not $modelEntry) {\n            $messageString = \"Unable to find the <c='em'>model.xml</c> file inside the archive. It would indicate the <c='em'>$Path</c> isn't a valid bacpac or dacpac.\"\n            Write-PSFMessage -Level Host -Message $messageString\n            Stop-PSFFunction -Message \"Stopping because model.xml wasn't found.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', '')))\n        }\n        \n        if (Test-PSFFunctionInterrupt) { return }\n\n        [System.IO.Compression.ZipFileExtensions]::ExtractToFile($modelEntry, $OutputPath, $true)\n\n        if ($zipArch) {\n            $zipArch.Dispose()\n        }\n\n        if ($file) {\n            $file.Close()\n            $file.Dispose()\n        }\n        \n        [PSCustomObject]@{\n            File     = $OutputPath\n            Filename = $(Split-Path -Path $OutputPath -Leaf)\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/export-d365model.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Export a model from Dynamics 365 for Finance & Operations\n        \n    .DESCRIPTION\n        Export a model from a Dynamics 365 for Finance & Operations environment\n        \n    .PARAMETER Path\n        Path to the folder where you want to save the model file\n        \n    .PARAMETER Model\n        Name of the model that you want to work against\n        \n    .PARAMETER Force\n        Instruct the cmdlet to overwrite already existing file\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the AOS service PackagesLocalDirectory\\bin\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .EXAMPLE\n        PS C:\\> Export-D365Model -Path c:\\temp\\d365fo.tools -Model CustomModelName\n        \n        This will export the \"CustomModelName\" model from the default PackagesLocalDirectory path.\n        It export the model to the \"c:\\temp\\d365fo.tools\" location.\n        \n    .NOTES\n        Tags: ModelUtil, Axmodel, Model, Export\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Export-D365Model {\n    [CmdletBinding()]\n    \n    param (\n        [Parameter(Mandatory = $true)]\n        [Alias('File')]\n        [string] $Path,\n\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]\n        [Alias('Modelname')]\n        [string] $Model,\n\n        [switch] $Force,\n\n        [string] $BinDir = \"$Script:PackageDirectory\\bin\",\n\n        [string] $MetaDataDir = \"$Script:MetaDataDir\",\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModelUtilExport\"),\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n    \n        if ($Path.EndsWith(\"\\\")) {\n            $Path = $Path.Substring(0, $Path.Length - 1)\n        }\n    }\n\n    process {\n\n        if($Force){\n            Get-ChildItem -Path \"$Path\\$Model-*.axmodel\" | Select-Object -First 1 | Remove-Item -Force -ErrorAction SilentlyContinue\n        }\n\n        Invoke-ModelUtil -Command \"Export\" -Path $Path -BinDir $BinDir -MetaDataDir $MetaDataDir -Model $Model -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        $file = Get-ChildItem -Path \"$Path\\$Model-*.axmodel\" | Select-Object -First 1\n        \n        [PSCustomObject]@{\n            File     = $file.FullName\n            Filename = (Split-Path $file.FullName -Leaf)\n        }\n    }\n    \n    end {\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/export-d365securitydetails.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Extract details from a User Interface Security file\n        \n    .DESCRIPTION\n        Extracts and partitions the security details from an User Interface Security file into the same structure as AOT security files\n        \n    .PARAMETER FilePath\n        Path to the User Interface Security XML file you want to work against\n        \n    .PARAMETER OutputDirectory\n        Path to the folder where the cmdlet will output and structure the details from the file.\n        The cmdlet will create a sub folder named like the input file.\n        \n        Default value is: \"C:\\temp\\d365fo.tools\\security-extraction\"\n        \n    .EXAMPLE\n        PS C:\\> Export-D365SecurityDetails -FilePath C:\\temp\\d365fo.tools\\SecurityDatabaseCustomizations.xml\n        \n        This will grab all the details inside the \"C:\\temp\\d365fo.tools\\SecurityDatabaseCustomizations.xml\" file and extract that into the default path \"C:\\temp\\d365fo.tools\\security-extraction\"\n        \n    .NOTES\n        \n        Tags: Security, Configuration, Permission, Development\n        \n        Author: Mötz Jensen (@splaxi)\n        \n        The work and design of this cmdlet is based on the findings by Alex Meyer (@alexmeyer_ITGuy).\n        \n        He wrote about his findings on his blog:\n        https://alexdmeyer.com/2018/09/26/converting-d365fo-user-interface-security-customizations-export-to-aot-security-xml-files/\n        \n        He published a github repository:\n        \n        https://github.com/ameyer505/D365FOSecurityConverter\n        \n        All credits goes to Alex Meyer\n#>\nfunction Export-D365SecurityDetails {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [Alias('Path')]\n        [string]$FilePath,\n\n        [Parameter(Mandatory = $false)]\n        [Alias('Output')]\n        [string]$OutputDirectory = \"C:\\temp\\d365fo.tools\\security-extraction\"\n    )\n    \n    begin { }\n    \n    process {\n\n        if (-not (Test-PathExists -Path $FilePath -Type Leaf)) { return }\n        if (-not (Test-PathExists -Path $OutputDirectory -Type Container)) { return }\n\n        [xml] $xdoc = Get-Content $FilePath\n        \n        $fileName = [System.IO.Path]::GetFileNameWithoutExtension($FilePath)\n        \n        $OutputDirectory = Join-Path $OutputDirectory $fileName\n\n        Write-PSFMessage -Level Verbose -Message \"Creating the output directory for the extraction\" -Target $OutputDirectory\n        $null = New-Item -Path $OutputDirectory -ItemType Directory -Force -ErrorAction SilentlyContinue\n\n        Write-PSFMessage -Level Verbose -Message \"Getting all the security objects.\"\n        $secObjects = $xdoc.SelectNodes(\"/*/*/*/*/*[starts-with(name(),'AxSec')]\")\n\n        if ($secObjects.Count -gt 0) {\n\n            Write-PSFMessage -Level Verbose -Message \"Looping through all the security objects we found\"\n            foreach ( $secObject in $secObjects) {\n                \n                $secPath = Join-Path $OutputDirectory $secObject.LocalName\n                \n                $null = New-Item -Path $secPath -ItemType Directory -Force -ErrorAction SilentlyContinue\n\n                $secObjectName = $secObject.Name\n                \n                if (-not ([string]::IsNullOrEmpty($secObjectName))) {\n                    $filePathOut = Join-Path $secPath $secObjectName\n                    $filePathOut += \".xml\"\n\n                    Write-PSFMessage -Level Verbose -Message \"Generating the output file: $filePathOut\" -Target $filePathOut\n                    $secObject.OuterXml | Out-File $filePathOut\n                }\n            }\n        }\n    }\n    \n    end {\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/find-d365command.ps1",
    "content": "﻿#ValidationTags#Messaging,FlowControl,Pipeline,CodeStyle#\nfunction Find-D365Command {\n<#\n    .SYNOPSIS\n        Finds d365fo.tools commands searching through the inline help text\n        \n    .DESCRIPTION\n        Finds d365fo.tools commands searching through the inline help text, building a consolidated json index and querying it because Get-Help is too slow\n        \n    .PARAMETER Tag\n        Finds all commands tagged with this auto-populated tag\n        \n    .PARAMETER Author\n        Finds all commands tagged with this author\n        \n    .PARAMETER MinimumVersion\n        Finds all commands tagged with this auto-populated minimum version\n        \n    .PARAMETER MaximumVersion\n        Finds all commands tagged with this auto-populated maximum version\n        \n    .PARAMETER Rebuild\n        Rebuilds the index\n        \n    .PARAMETER Pattern\n        Searches help for all commands in d365fo.tools for the specified pattern and displays all results\n        \n    .PARAMETER Confirm\n        Confirms overwrite of index\n        \n    .PARAMETER WhatIf\n        Displays what would happen if the command is run\n        \n    .PARAMETER EnableException\n        By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message.\n        This avoids overwhelming you with \"sea of red\" exceptions, but is inconvenient because it basically disables advanced scripting.\n        Using this switch turns this \"nice by default\" feature off and enables you to catch exceptions with your own try/catch.\n        \n    .EXAMPLE\n        PS C:\\> Find-D365Command \"snapshot\"\n        \n        For lazy typers: finds all commands searching the entire help for \"snapshot\"\n        \n    .EXAMPLE\n        PS C:\\> Find-D365Command -Pattern \"snapshot\"\n        \n        For rigorous typers: finds all commands searching the entire help for \"snapshot\"\n        \n    .EXAMPLE\n        PS C:\\> Find-D365Command -Tag copy\n        \n        Finds all commands tagged with \"copy\"\n        \n    .EXAMPLE\n        PS C:\\> Find-D365Command -Tag copy,user\n        \n        Finds all commands tagged with BOTH \"copy\" and \"user\"\n        \n    .EXAMPLE\n        PS C:\\> Find-D365Command -Author Mötz\n        \n        Finds every command whose author contains \"Mötz\"\n        \n    .EXAMPLE\n        PS C:\\> Find-D365Command -Author Mötz -Tag copy\n        \n        Finds every command whose author contains \"Mötz\" and it tagged as \"copy\"\n        \n    .EXAMPLE\n        PS C:\\> Find-D365Command -Pattern snapshot -Rebuild\n        \n        Finds all commands searching the entire help for \"snapshot\", rebuilding the index (good for developers)\n        \n    .NOTES\n        Tags: Find, Help, Command\n        Author: Mötz Jensen (@Splaxi)\n        \n        License: MIT https://opensource.org/licenses/MIT\n        \n        This cmdlet / function is copy & paste implementation based on the Find-DbaCommand from the dbatools.io project\n        \n        Original author: Simone Bizzotto (@niphold)\n        \n#>\n        [CmdletBinding(SupportsShouldProcess = $true)]\n        param (\n            [String]$Pattern,\n            [String[]]$Tag,\n            [String]$Author,\n            [String]$MinimumVersion,\n            [String]$MaximumVersion,\n            [switch]$Rebuild,\n            [Alias('Silent')]\n            [switch]$EnableException\n        )\n        begin {\n            function Get-D365TrimmedString($Text) {\n                return $Text.Trim() -replace '(\\r\\n){2,}', \"`n\"\n            }\n    \n            $tagsRex = ([regex]'(?m)^[\\s]{0,15}Tags:(.*)$')\n            $authorRex = ([regex]'(?m)^[\\s]{0,15}Author:(.*)$')\n            $minverRex = ([regex]'(?m)^[\\s]{0,15}MinimumVersion:(.*)$')\n            $maxverRex = ([regex]'(?m)^[\\s]{0,15}MaximumVersion:(.*)$')\n    \n            function Get-D365Help([String]$commandName) {\n                $thishelp = Get-Help $commandName -Full\n                $thebase = @{ }\n                $thebase.CommandName = $commandName\n                $thebase.Name = $thishelp.Name\n    \n                $alias = Get-Alias -Definition $commandName -ErrorAction SilentlyContinue\n                $thebase.Alias = $alias.Name -Join ','\n    \n                ## fetch the description\n                $thebase.Description = $thishelp.Description.Text\n    \n                ## fetch examples\n                $thebase.Examples = Get-D365TrimmedString -Text ($thishelp.Examples | Out-String -Width 200)\n    \n                ## fetch help link\n                $thebase.Links = ($thishelp.relatedLinks).NavigationLink.Uri\n    \n                ## fetch the synopsis\n                $thebase.Synopsis = $thishelp.Synopsis\n    \n                ## fetch the syntax\n                $thebase.Syntax = Get-D365TrimmedString -Text ($thishelp.Syntax | Out-String -Width 600)\n    \n                ## store notes\n                $as = $thishelp.AlertSet | Out-String -Width 600\n    \n                ## fetch the tags\n                $tags = $tagsrex.Match($as).Groups[1].Value\n                if ($tags) {\n                    $thebase.Tags = $tags.Split(',').Trim()\n                }\n                ## fetch the author\n                $author = $authorRex.Match($as).Groups[1].Value\n                if ($author) {\n                    $thebase.Author = $author.Trim()\n                }\n    \n                ## fetch MinimumVersion\n                $MinimumVersion = $minverRex.Match($as).Groups[1].Value\n                if ($MinimumVersion) {\n                    $thebase.MinimumVersion = $MinimumVersion.Trim()\n                }\n    \n                ## fetch MaximumVersion\n                $MaximumVersion = $maxverRex.Match($as).Groups[1].Value\n                if ($MaximumVersion) {\n                    $thebase.MaximumVersion = $MaximumVersion.Trim()\n                }\n    \n                ## fetch Parameters\n                $parameters = $thishelp.parameters.parameter\n                $command = Get-Command $commandName\n                $params = @()\n                foreach($p in $parameters) {\n                    $paramAlias = $command.parameters[$p.Name].Aliases\n                    $paramDescr = Get-D365TrimmedString -Text ($p.Description | Out-String -Width 200)\n                    $params += , @($p.Name, $paramDescr, ($paramAlias -Join ','), ($p.Required -eq $true), $p.PipelineInput, $p.DefaultValue)\n                }\n    \n                $thebase.Params = $params\n    \n                [pscustomobject]$thebase\n            }\n    \n            function Get-D365Index() {\n                if ($Pscmdlet.ShouldProcess($dest, \"Recreating index\")) {\n                    $dbamodule = Get-Module -Name d365fo.tools\n                    $allCommands = $dbamodule.ExportedCommands.Values | Where-Object CommandType -EQ 'Function'\n    \n                    $helpcoll = New-Object System.Collections.Generic.List[System.Object]\n                    foreach ($command in $allCommands) {\n                        $x = Get-D365Help \"$command\"\n                        $helpcoll.Add($x)\n                    }\n                    # $dest = Get-DbatoolsConfigValue -Name 'Path.TagCache' -Fallback \"$(Resolve-Path $PSScriptRoot\\..)\\dbatools-index.json\"\n                    $dest = \"$moduleDirectory\\bin\\d365fo.tools-index.json\"\n                    $helpcoll | ConvertTo-Json -Depth 4 | Out-File $dest -Encoding UTF8\n                }\n            }\n    \n            $moduleDirectory = (Get-Module -Name d365fo.tools).ModuleBase\n        }\n        process {\n            $Pattern = $Pattern.TrimEnd(\"s\")\n            $idxFile = \"$moduleDirectory\\bin\\d365fo.tools-index.json\"\n            if (!(Test-Path $idxFile) -or $Rebuild) {\n                Write-PSFMessage -Level Verbose -Message \"Rebuilding index into $idxFile\"\n                $swRebuild = [system.diagnostics.stopwatch]::StartNew()\n                Get-D365Index\n                Write-PSFMessage -Level Verbose -Message \"Rebuild done in $($swRebuild.ElapsedMilliseconds)ms\"\n            }\n            $consolidated = Get-Content -Raw $idxFile | ConvertFrom-Json\n            $result = $consolidated\n            if ($Pattern.Length -gt 0) {\n                $result = $result | Where-Object { $_.PsObject.Properties.Value -like \"*$Pattern*\" }\n            }\n    \n            if ($Tag.Length -gt 0) {\n                foreach ($t in $Tag) {\n                    $result = $result | Where-Object Tags -Contains $t\n                }\n            }\n    \n            if ($Author.Length -gt 0) {\n                $result = $result | Where-Object Author -Like \"*$Author*\"\n            }\n    \n            if ($MinimumVersion.Length -gt 0) {\n                $result = $result | Where-Object MinimumVersion -GE $MinimumVersion\n            }\n    \n            if ($MaximumVersion.Length -gt 0) {\n                $result = $result | Where-Object MaximumVersion -LE $MaximumVersion\n            }\n    \n            Select-DefaultView -InputObject $result -Property CommandName, Synopsis\n        }\n    }"
  },
  {
    "path": "d365fo.tools/functions/get-d365activeazurestorageconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get active Azure Storage Account configuration\n        \n    .DESCRIPTION\n        Get active Azure Storage Account configuration object from the configuration store\n        \n    .PARAMETER OutputAsPsCustomObject\n        Instruct the cmdlet to return a PsCustomObject object\n        \n    .EXAMPLE\n        PS C:\\> Get-D365ActiveAzureStorageConfig\n        \n        This will get the active Azure Storage configuration.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365ActiveAzureStorageConfig -OutputAsPsCustomObject\n        \n        This will get the active Azure Storage configuration.\n        The object will be output as a PsCustomObject, for you to utilize across your scripts.\n        \n    .NOTES\n        Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, Container\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-D365ActiveAzureStorageConfig {\n    [CmdletBinding()]\n    param (\n        [switch] $OutputAsPsCustomObject\n    )\n\n    $res = Get-PSFConfigValue -FullName \"d365fo.tools.active.azure.storage.account\"\n\n    if ($OutputAsPsCustomObject) {\n        [PSCustomObject]$res\n    }\n    else {\n        $res\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365activebroadcastmessageconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get active broadcast message configuration\n        \n    .DESCRIPTION\n        Get active broadcast message configuration from the configuration store\n        \n    .PARAMETER OutputAsHashtable\n        Instruct the cmdlet to return a hastable object\n        \n    .EXAMPLE\n        PS C:\\> Get-D365ActiveBroadcastMessageConfig\n        \n        This will get the active broadcast message configuration.\n        \n    .NOTES\n        Tags: Servicing, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n    .LINK\n        Add-D365BroadcastMessageConfig\n        \n    .LINK\n        Clear-D365ActiveBroadcastMessageConfig\n        \n    .LINK\n        Get-D365BroadcastMessageConfig\n        \n    .LINK\n        Remove-D365BroadcastMessageConfig\n        \n    .LINK\n        Send-D365BroadcastMessage\n        \n    .LINK\n        Set-D365ActiveBroadcastMessageConfig\n#>\n\nfunction Get-D365ActiveBroadcastMessageConfig {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [switch] $OutputAsHashtable\n    )\n\n    $configName = (Get-PSFConfig -FullName \"d365fo.tools.active.broadcast.message.config.name\").Value\n\n    if ($configName -eq \"\") {\n        Write-PSFMessage -Level Host -Message \"It looks like there <c='em'>isn't configured</c> an active broadcast message configuration.\"\n        Stop-PSFFunction -Message \"Stopping because an active broadcast message configuration wasn't found.\"\n        return\n    }\n\n    Get-D365BroadcastMessageConfig -Name $configName -OutputAsHashtable:$OutputAsHashtable\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365aotobject.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Search for AOT object\n        \n    .DESCRIPTION\n        Enables you to search for different AOT objects\n        \n    .PARAMETER Path\n        Path to the package that you want to work against\n        \n    .PARAMETER ObjectType\n        The type of AOT object you're searching for\n        \n    .PARAMETER Name\n        Name of the object that you're looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"Work*status\"\n        \n        Default value is \"*\" which will search for all objects\n        \n    .PARAMETER SearchInPackages\n        Switch to instruct the cmdlet to search in packages directly instead\n        of searching in the XppMetaData directory under a given package\n        \n    .PARAMETER IncludePath\n        Switch to instruct the cmdlet to include the path for the object found\n        \n    .EXAMPLE\n        PS C:\\> Get-D365AOTObject -Name *flush* -ObjectType AxClass -Path \"C:\\AOSService\\PackagesLocalDirectory\\ApplicationFoundation\"\n        \n        This will search inside the ApplicationFoundation package for all AxClasses that matches the search *flush*.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365AOTObject -Name *flush* -ObjectType AxClass -IncludePath -Path \"C:\\AOSService\\PackagesLocalDirectory\\ApplicationFoundation\"\n        \n        This will search inside the ApplicationFoundation package for all AxClasses that matches the search *flush* and include the full path to the files.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365InstalledPackage -Name Application* | Get-D365AOTObject -Name *flush* -ObjectType AxClass\n        \n        This searches for all packages that matches Application* and pipes them into Get-D365AOTObject which will search for all AxClasses that matches the search *flush*.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365AOTObject -Path \"C:\\AOSService\\PackagesLocalDirectory\\*\" -Name *flush* -ObjectType AxClass -SearchInPackages\n        \n        This is an advanced example and shouldn't be something you resolve to every time.\n        \n        This will search across all packages and will look for the all AxClasses that matches the search *flush*.\n        It will NOT search in the XppMetaData directory for each package.\n        \n        This can stress your system.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-D365AOTObject {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]\n        [Alias('PackageDirectory')]\n        [string] $Path,\n\n        [ValidateSet('AxAggregateDataEntity', 'AxClass', 'AxCompositeDataEntityView',\n            'AxDataEntityView', 'AxForm', 'AxMap', 'AxQuery', 'AxTable', 'AxView')]\n        [Alias('Type')]\n        [string[]] $ObjectType = @(\"AxClass\"),\n\n        [string] $Name = \"*\",\n\n        [switch] $SearchInPackages,\n\n        [switch] $IncludePath\n    )\n    \n    begin {\n        \n    }\n    \n    process {\n        $SearchList = New-Object -TypeName \"System.Collections.ArrayList\"\n\n        foreach ($item in $ObjectType) {\n            if ($SearchInPackages) {\n                $SearchParent = Split-Path $Path -Leaf\n\n                $null = $SearchList.Add((Join-Path \"$Path\" \"\\$SearchParent\\$item\\*.xml\"))\n                $SearchParent = $item #* Hack to make the logic when selecting the output work as expected\n            }\n            else {\n                $SearchParent = \"XppMetadata\"\n\n                $null = $SearchList.Add((Join-Path \"$Path\" \"\\$SearchParent\\*\\$item\\*.xml\"))\n            }\n        }\n        \n        #* We are searching files - so the last character has to be a *\n        if($Name.Substring($Name.Length -1, 1) -ne \"*\") {$Name = \"$Name*\"}\n\n        $Files = Get-ChildItem -Path ($SearchList.ToArray()) -Filter $Name\n\n        if($IncludePath) {\n            $Files | Select-PSFObject -TypeName \"D365FO.TOOLS.AotObject\" \"BaseName as Name\",\n            @{Name = \"AotType\"; Expression = {Split-Path(Split-Path -Path $_.Fullname -Parent) -leaf }},\n            @{Name = \"Model\"; Expression = {Split-Path(($_.Fullname -Split $SearchParent)[0] ) -leaf }},\n            \"Fullname as Path\"\n        }\n        else {\n            $Files | Select-PSFObject -TypeName \"D365FO.TOOLS.AotObject\" \"BaseName as Name\",\n            @{Name = \"AotType\"; Expression = {Split-Path(Split-Path -Path $_.Fullname -Parent) -leaf }},\n            @{Name = \"Model\"; Expression = {Split-Path(($_.Fullname -Split $SearchParent)[0] ) -leaf }}\n        }\n    }\n    \n    end {\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365azuredevopsnuget.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get Azure DevOps nugets\n        \n    .DESCRIPTION\n        Get Azure DevOps nugets from a feed, to list all available details\n        \n    .PARAMETER Url\n        The Azure DevOps url that you want to work against\n        \n        It needs to be the full url for the organization and project, e.g. \"https://dev.azure.com/Contoso/Financials\" - where Contoso is the organization and the Financials is the project.\n        \n    .PARAMETER FeedName\n        Name of the feed that you want to work against\n        \n        The feed name is found under the Artifacts area in Azure DevOps\n        \n    .PARAMETER PeronalAccessToken\n        The Personal Access Token that you need to provide for the cmdlet to be able to communicate with the Azure DevOps REST services\n        \n        The Personal Access Token is configured via the Azure DevOps portal, on your own account\n        \n    .PARAMETER Name\n        Name of the package / nuget that you are searching for\n        \n        Supports wildcard searching e.g. \"*platform*\" will output all packages / nugets that matches the search pattern\n        \n        Default value is \"*\" which will search for all packages / nugets\n        \n    .PARAMETER Latest\n        Instruct the cmdlet to only fetch the latest package / nuget based on the version (highest)\n        \n    .EXAMPLE\n        PS C:\\> Get-D365AzureDevOpsNuget -Uri \"https://dev.azure.com/Contoso/Financials\" -FeedName \"AASBuild365\" -PeronalAccessToken \"m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny\"\n        \n        This will list all packages / nugets from the Azure DevOps feed. Foreach packacge, it will list all available versions.\n        The http request will be going to the Uri \"https://dev.azure.com/Contoso/Financials\".\n        The feed is identified by the FeedName \"AASBuild365\".\n        The request will authenticate with the PeronalAccessToken \"m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny\"\n        \n    .EXAMPLE\n        PS C:\\> Get-D365AzureDevOpsNuget -Uri \"https://dev.azure.com/Contoso/Financials\" -FeedName \"AASBuild365\" -PeronalAccessToken \"m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny\" -Latest\n        \n        This will list all packages / nugets from the Azure DevOps feed. Foreach packacge, it will only list the latest version (highest).\n        The http request will be going to the Uri \"https://dev.azure.com/Contoso/Financials\".\n        The feed is identified by the FeedName \"AASBuild365\".\n        The request will authenticate with the PeronalAccessToken \"m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny\"\n        The cmdlet will only output the latest version by the Latest switch.\n        \n    .EXAMPLE\n        PS C:\\> $currentNugets = Get-D365AzureDevOpsNuget -Uri \"https://dev.azure.com/Contoso/Financials\" -FeedName \"AASBuild365\" -PeronalAccessToken \"m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny\" -Latest\n        PS C:\\> foreach ($item in $currentNugets) {\n        PS C:\\>     $lcsNugets = Get-D365LcsAssetFile -FileType NuGetPackage -AssetFilename \"$($item.Name)*\"\n        PS C:\\>     foreach ($itemInner in $lcsNugets) {\n        PS C:\\>         if ($itemInner.FileName -Match \"\\d+\\.\\d+\\.\\d+\\.\\d+\") {\n        PS C:\\>             if ($([Version]$Matches[0]) -gt [Version]$item.Version) {\n        PS C:\\>                 $itemInner\n        PS C:\\>             }\n        PS C:\\>         }\n        PS C:\\>     }\n        PS C:\\> }\n        \n        This will fetch all latest nugets from the Azure DevOps artifacts feed (nuget).\n        For each nuget found, it will fetch matching nugets from the LCS Asset Library and return those that have a higher version.\n        \n        This can be used to automatically download and push the latest nuget from LCS to Azure DevOps.\n        Needs to be put into work with Invoke-D365AzureDevOpsNugetPush\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Get-D365AzureDevOpsNuget {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [Alias('Uri')]\n        [string] $Url,\n\n        [Parameter(Mandatory = $true)]\n        [string] $FeedName,\n\n        [Parameter(Mandatory = $true)]\n        [string] $PeronalAccessToken,\n\n        [Alias('PackageName')]\n        [string] $Name = \"*\",\n\n        [switch] $Latest\n    )\n    \n    begin {\n        if ($Url -notlike \"https://dev.azure.com/*/*\") {\n            $messageString = \"The supplied uri is not in a valid format. Please enter the project uri like <c='em'>https://dev.azure.com/[ORGANIZATION]]/[PROJECT]</c>.\"\n            Write-PSFMessage -Level Host -Message $messageString\n            Stop-PSFFunction -Message \"Stopping because the uri is wrongly formatted.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', '')))\n            return\n        }\n        else {\n            $uriPackages = $Url.Replace(\"https://dev.azure.com\", \"https://feeds.dev.azure.com\") + \"/_apis/packaging/Feeds/{0}/packages?api-version=6.0-preview.1&includeAllVersions=true\"\n\n            if ($Name -NotMatch '\\*') {\n                $uriPackages += \"&packageNameQuery={1}\"\n            }\n\n            $uriFeeds = $Url.Replace(\"https://dev.azure.com\", \"https://feeds.dev.azure.com\") + \"/_apis/packaging/Feeds?api-version=6.0-preview.1\"\n        }\n\n        $header = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(\":$($PeronalAccessToken)\")) }\n\n    }\n    \n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n\n        $feedsRaw = Invoke-RestMethod -Method Get -Uri $uriFeeds -Headers $header\n\n        $feeds = @($feedsRaw | Select-Object -ExpandProperty Value)\n\n        $feed = $feeds | Where-Object Name -like $FeedName | Select-Object -First 1\n\n        if (-not $feed) {\n            $messageString = \"No feed found that matched the provided feedname <c='em'>$feedname</c>.\"\n            Write-PSFMessage -Level Host -Message $messageString\n            Stop-PSFFunction -Message \"Stopping because the feed couldn't be located.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', '')))\n            return\n        }\n\n        $uriPackages = $uriPackages -f $($feed.Id), $Name\n\n        $packagesRaw = Invoke-RestMethod -Method Get -Uri $uriPackages -Headers $header\n\n        $packages = @($packagesRaw | Select-Object -ExpandProperty value)\n\n        foreach ($item in $packages) {\n            if ($item.Name -NotLike $Name) { continue }\n\n            foreach ($itemInner in $item.versions) {\n                if ($Latest) {\n                    if (-not $itemInner.IsLatest) { continue }\n                }\n\n                [PSCustomObject][ordered]@{\n                    Name       = $item.Name\n                    Version    = [Version]$itemInner.Version\n                    VersionId  = $itemInner.Id\n                    IsLatest   = $itemInner.IsLatest\n                    PackageId  = $item.Id\n                    PackageUrl = $item.Url\n\n                }\n            }\n        }\n    }\n    \n    end {\n        \n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365azurestorageconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get Azure Storage Account configs\n        \n    .DESCRIPTION\n        Get all Azure Storage Account configuration objects from the configuration store\n        \n    .PARAMETER Name\n        The name of the Azure Storage Account you are looking for\n        \n        Default value is \"*\" to display all Azure Storage Account configs\n        \n    .PARAMETER OutputAsHashtable\n        Instruct the cmdlet to return a hastable object\n        \n    .EXAMPLE\n        PS C:\\> Get-D365AzureStorageConfig\n        \n        This will show all Azure Storage Account configs\n        \n    .EXAMPLE\n        PS C:\\> Get-D365AzureStorageConfig -OutputAsHashtable\n        \n        This will show all Azure Storage Account configs.\n        Every object will be output as a hashtable, for you to utilize as parameters for other cmdlets.\n        \n    .NOTES\n        Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, Container\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-D365AzureStorageConfig {\n    [CmdletBinding()]\n    param (\n        [string] $Name = \"*\",\n\n        [switch] $OutputAsHashtable\n    )\n    \n    $StorageAccounts = [hashtable](Get-PSFConfigValue -FullName \"d365fo.tools.azure.storage.accounts\")\n        \n    foreach ($item in $StorageAccounts.Keys) {\n        if ($item -NotLike $Name) { continue }\n        $res = [ordered]@{Name = $item }\n        $res += $StorageAccounts[$item]\n\n        if ($OutputAsHashtable) {\n            $res\n        }\n        else {\n            [PSCustomObject]$res\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365azurestoragefile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get file information from Azure Storage\n        \n    .DESCRIPTION\n        Get information for files from an Azure Storage Account\n        \n    .PARAMETER AccountId\n        Storage Account Name / Storage Account Id where file information should be retrieved from\n        \n    .PARAMETER AccessToken\n        The token that has the needed permissions for the search action\n        \n    .PARAMETER SAS\n        The SAS key for the storage account or blob container\n        \n    .PARAMETER Container\n        Name of the blob container inside the storage account where file information should be retrieved from\n        \n    .PARAMETER Name\n        Name of the files information should be retrieved for\n        \n        Accepts wildcards for searching. E.g. -Name \"Application*Adaptor\"\n        \n        Default value is \"*\" which will search for all files\n        \n    .PARAMETER Latest\n        Instruct the cmdlet to only fetch the information of the latest file from the Azure Storage Account\n        \n    .EXAMPLE\n        PS C:\\> Get-D365AzureStorageFile -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Container \"backupfiles\"\n        \n        This will get information for all files in the blob container \"backupfiles\".\n        It will use the AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" to gain access.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365AzureStorageFile -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Container \"backupfiles\" -Latest\n        \n        This will get information for the latest (newest) file from the blob container \"backupfiles\".\n        It will use the AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" to gain access to the container.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365AzureStorageFile -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Container \"backupfiles\" -Name \"*UAT*\"\n        \n        This will get information for all files in the blob container \"backupfiles\" that fits the \"*UAT*\" search value.\n        It will use the AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" to gain access to the container.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365AzureStorageFile -AccountId \"miscfiles\" -SAS \"sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" -Container \"backupfiles\" -Latest\n        \n        This will get information for the latest (newest) file from the blob container \"backupfiles\".\n        It will use the SAS key \"sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" to gain access to the container.\n        \n    .NOTES\n        Tags: Azure, Azure Storage, Token, Blob, File, Container\n        \n        Author: Mötz Jensen (@Splaxi)\n        Author: Florian Hopfner (@FH-Inway)\n#>\nfunction Get-D365AzureStorageFile {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [string] $AccountId = $Script:AzureStorageAccountId,\n\n        [string] $AccessToken = $Script:AzureStorageAccessToken,\n\n        [string] $SAS = $Script:AzureStorageSAS,\n\n        [Alias('Blob')]\n        [Alias('Blobname')]\n        [string] $Container = $Script:AzureStorageContainer,\n\n        [Parameter(ParameterSetName = 'Default')]\n        [Alias('FileName')]\n        [string] $Name = \"*\",\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'Latest')]\n        [Alias('GetLatest')]\n        [switch] $Latest\n    )\n\n    $connectionInformation = ($AccountId -and $Container)\n    $authenticationInformation = ($AccessToken -or $SAS)\n    if (-not ($connectionInformation -and $authenticationInformation)) {\n        Write-PSFMessage -Level Host -Message \"It seems that you are missing some of the parameters. Please make sure that you either supplied them or have the right configuration saved.\"\n        Stop-PSFFunction -Message \"Stopping because of missing parameters\"\n        return\n    }\n\n    Invoke-TimeSignal -Start\n\n    if ([string]::IsNullOrEmpty($SAS)) {\n        Write-PSFMessage -Level Verbose -Message \"Working against Azure Storage Account with AccessToken\"\n\n        $storageContext = New-AzStorageContext -StorageAccountName $AccountId.ToLower() -StorageAccountKey $AccessToken\n    }\n    else {\n        Write-PSFMessage -Level Verbose -Message \"Working against Azure Storage Account with SAS\"\n\n        $conString = $(\"BlobEndpoint=https://{0}.blob.core.windows.net/;QueueEndpoint=https://{0}.queue.core.windows.net/;FileEndpoint=https://{0}.file.core.windows.net/;TableEndpoint=https://{0}.table.core.windows.net/;SharedAccessSignature={1}\" -f $AccountId.ToLower(), $SAS)\n        $storageContext = New-AzStorageContext -ConnectionString $conString\n    }\n\n    try {\n        $files = Get-AzStorageBlob -Container $($Container.ToLower()) -Context $storageContext |\n            Sort-Object -Descending { $_.LastModified }\n\n        $selectParams = @{\n            TypeName = \"D365FO.TOOLS.Azure.Blob\"\n            Property = \"Name\", \"Length as Size to PSFSize\", \"LastModified\"\n        }\n        if ($Latest) {\n            $files |\n                Select-Object -First 1 |\n                Select-PSFObject @selectParams\n        }\n        else {\n            $filteredFiles = $files | Where-Object { $_.Name -Like $Name }\n            foreach ($fileInfo in $filteredFiles) {\n                $fileInfo | Select-PSFObject @selectParams\n            }\n        }\n    }\n    catch {\n        Write-PSFMessage -Level Warning -Message \"Something broke\" -ErrorRecord $_\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365azurestorageurl.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get a blob Url from Azure Storage account\n        \n    .DESCRIPTION\n        Get a valid blob container url from an Azure Storage Account\n        \n    .PARAMETER AccountId\n        Storage Account Name / Storage Account Id you want to work against\n        \n    .PARAMETER SAS\n        The SAS key that you have created for the storage account or blob container\n        \n    .PARAMETER Container\n        Name of the blob container inside the storage account you want to work against\n        \n    .PARAMETER OutputAsHashtable\n        Instruct the cmdlet to return a hastable object\n        \n    .EXAMPLE\n        PS C:\\> Get-D365AzureStorageUrl -AccountId \"miscfiles\" -SAS \"sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" -Container \"backupfiles\"\n        \n        This will generate a valid Url for the blob container in the Azure Storage Account.\n        It will use the AccountId \"miscfiles\" as the name of the storage account.\n        It will use the SAS key \"sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" to add the SAS token/key to the Url.\n        It will use the Container \"backupfiles\" as the container name in the Url.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365AzureStorageUrl\n        \n        This will generate a valid Url for the blob container in the Azure Storage Account.\n        It will use the default values that are configured using the Set-D365ActiveAzureStorageConfig cmdlet and view using the Get-D365ActiveAzureStorageConfig cmdlet.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365AzureStorageUrl -OutputAsHashtable\n        \n        This will generate a valid Url for the blob container in the Azure Storage Account.\n        It will use the default values that are configured using the Set-D365ActiveAzureStorageConfig cmdlet and view using the Get-D365ActiveAzureStorageConfig cmdlet.\n        \n        The output object will be a Hashtable, which you can use as a parameter for other cmdlets.\n        \n    .EXAMPLE\n        PS C:\\> $DestinationParms = Get-D365AzureStorageUrl -OutputAsHashtable\n        PS C:\\> $BlobFileDetails = Get-D365LcsDatabaseBackups -Latest | Invoke-D365AzCopyTransfer @DestinationParms\n        PS C:\\> $BlobFileDetails | Invoke-D365AzCopyTransfer -DestinationUri \"C:\\Temp\" -DeleteOnTransferComplete\n        \n        This will transfer the lastest backup file from LCS Asset Library to your local \"C:\\Temp\".\n        It will get a destination Url, for it to transfer the backup file between the LCS storage account and your own.\n        The newly transfered file, that lives in your own storage account, will then be downloaded to your local \"c:\\Temp\".\n        \n        After the file has been downloaded to your local \"C:\\Temp\", it will be deleted from your own storage account.\n        \n    .NOTES\n        Tags: Azure, Azure Storage, Token, Blob, File, Container, LCS, Asset, Bacpac, Backup\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Get-D365AzureStorageUrl {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')]\n    [CmdletBinding()]\n    param (\n        [string] $AccountId = $Script:AzureStorageAccountId,\n\n        [string] $SAS = $Script:AzureStorageSAS,\n\n        [Alias('Blob')]\n        [Alias('Blobname')]\n        [string] $Container = $Script:AzureStorageContainer,\n\n        [switch] $OutputAsHashtable\n    )\n\n    if (([string]::IsNullOrEmpty($AccountId) -eq $true) -or\n        ([string]::IsNullOrEmpty($Container)) -or\n        ([string]::IsNullOrEmpty($SAS))) {\n        Write-PSFMessage -Level Host -Message \"It seems that you are missing some of the parameters. Please make sure that you either supplied them or have the right configuration saved.\"\n        Stop-PSFFunction -Message \"Stopping because of missing parameters\"\n        return\n    }\n\n    Invoke-TimeSignal -Start\n\n    if ($SAS.StartsWith(\"?\")) {\n        $SAS = $SAS.Substring(1)\n    }\n\n    $res = @{\n        DestinationUri = $(\"https://{0}.blob.core.windows.net/{1}?{2}\" -f $AccountId.ToLower(), $Container, $SAS)\n    }\n\n    if ($OutputAsHashtable) {\n        $res\n    }\n    else {\n        [PSCustomObject]$res\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365bacpacsqloptions.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the SQL Server options from the bacpac model.xml file\n        \n    .DESCRIPTION\n        Extract the SQL Server options that are listed inside the model.xml file originating from a bacpac file\n        \n    .PARAMETER Path\n        Path to the extracted model.xml file that you want to work against\n        \n    .EXAMPLE\n        PS C:\\> Get-D365BacpacSqlOptions -Path \"c:\\temp\\d365fo.tools\\bacpac.model.xml\"\n        \n        This will display all the SQL Server options configured in the bacpac model file.\n        \n    .EXAMPLE\n        PS C:\\> Export-D365BacpacModelFile -Path \"c:\\Temp\\AxDB.bacpac\" | Get-D365BacpacSqlOptions\n        \n        This will display all the SQL Server options configured in the bacpac file.\n        First it will export the model.xml from the \"c:\\Temp\\AxDB.bacpac\" file, using the Export-D365BacpacModelFile function.\n        The output from Export-D365BacpacModelFile will be piped into the Get-D365BacpacSqlOptions function.\n        \n    .NOTES\n        Tags: Bacpac, Servicing, Data, SqlPackage, Sql Server Options, Collation\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Get-D365BacpacSqlOptions {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [Alias(\"Get-D365SqlOptionsFromBacpacModelFile\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(ValueFromPipelineByPropertyName = $true)]\n        [Alias('ModelFile')]\n        [Alias('File')]\n        [string] $Path\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n    }\n\n    process {\n        if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n    \n        $reader = [System.Xml.XmlReader]::Create($Path)\n\n        $break = $false\n        while ($reader.read() -and -not ($break)) {\n            switch ($reader.NodeType) {\n                ([System.Xml.XmlNodeType]::Element) {\n                    if ($reader.Name -eq \"Element\") {\n                        if ($reader.GetAttribute(\"Type\") -eq \"SqlDatabaseOptions\") {\n                            if ($reader.ReadToDescendant(\"Property\")) {\n                                do {\n                                    [PSCustomObject]@{OptionName = $reader.GetAttribute(\"Name\")\n                                        OptionValue              = $reader.GetAttribute(\"Value\")\n                                    }\n\n                                } while ($reader.ReadToNextSibling(\"Property\"))\n\n                            }\n\n                            $break = $true\n                            break\n                        }\n                    }\n\n                    break\n                }\n            }\n        }\n    }\n\n    end {\n        if ($reader) {\n            $reader.Close()\n            $reader.Dispose()\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365bacpactable.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get tables from the bacpac file\n        \n    .DESCRIPTION\n        Get tables and their metadata from the bacpac file\n        \n        Metadata as in original size and compressed size, which are what size the bulk files are and will only indicate what you can expect of the table size\n        \n    .PARAMETER Path\n        Path to the bacpac file that you want to work against\n        \n        It can also be a zip file\n        \n    .PARAMETER Table\n        Name of the table that you want to delete the data for\n        \n        Supports an array of table names\n        \n        If a schema name isn't supplied as part of the table name, the cmdlet will prefix it with \"dbo.\"\n        \n        Supports wildcard searching e.g. \"Sales*\" will locate all \"dbo.Sales*\" tables in the bacpac file\n        \n    .PARAMETER Top\n        Instruct the cmdlet with how many tables you want returned\n        \n        Default is [int]::max, which translates into all tables present inside the bapcac file\n        \n    .PARAMETER SortSizeAsc\n        Instruct the cmdlet to sort the output by size (original) ascending\n        \n    .PARAMETER SortSizeDesc\n        Instruct the cmdlet to sort the output by size (original) descending\n        \n    .EXAMPLE\n        PS C:\\> Get-D365BacpacTable -Path \"c:\\Temp\\AxDB.bacpac\"\n        \n        This will return all tables from inside the bacpac file.\n        \n        It uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\n        It uses the default value \"*\" as the Table parameter, to output all tables.\n        It uses the default value \"[int]::max\" as the Top parameter, to output all tables.\n        It uses the default sort, which is by name acsending.\n        \n        A result set example:\n        \n        Name                                                                   OriginalSize CompressedSize BulkFiles\n        ----                                                                   ------------ -------------- ---------\n        ax.DBVERSION                                                                   62 B           52 B         1\n        crt.RETAILUPGRADEHISTORY                                                   13,49 MB       13,41 MB         3\n        dbo.__AOSMESSAGEREGISTRATION                                                1,80 KB          540 B         2\n        dbo.__AOSSTARTUPVERSION                                                         4 B            6 B         1\n        dbo.ACCOUNTINGDISTRIBUTION                                                 48,60 MB        4,50 MB        95\n        dbo.ACCOUNTINGEVENT                                                        11,16 MB        1,51 MB       128\n        dbo.AGREEMENTPARAMETERS_RU                                                    366 B          113 B         1\n        dbo.AIFSQLCDCENABLEDTABLES                                                 13,63 KB        2,19 KB         1\n        dbo.AIFSQLCHANGETRACKINGENABLEDTABLES                                       9,89 KB        1,42 KB         1\n        dbo.AIFSQLCTTRIGGERS                                                       44,75 KB        6,29 KB         1\n        \n    .EXAMPLE\n        PS C:\\> Get-D365BacpacTable -Path \"c:\\Temp\\AxDB.bacpac\" -SortSizeAsc\n        \n        This will return all tables from inside the bacpac file, sorted by the original size, ascending.\n        \n        It uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\n        It uses the default value \"*\" as the Table parameter, to output all tables.\n        It uses the default value \"[int]::max\" as the Top parameter, to output all tables.\n        It uses the SortSizeAsc parameter, which is by original size acsending.\n        \n        A result set example:\n        \n        Name                                                                   OriginalSize CompressedSize BulkFiles\n        ----                                                                   ------------ -------------- ---------\n        dbo.__AOSSTARTUPVERSION                                                         4 B            6 B         1\n        dbo.SYSSORTORDER                                                               20 B           20 B         1\n        dbo.SECURITYDATABASESETTINGS                                                   20 B           12 B         1\n        dbo.SYSPOLICYSEQUENCEGROUP                                                     24 B           10 B         1\n        dbo.SYSFILESTOREPARAMETERS                                                     26 B           10 B         1\n        dbo.SYSHELPCPSSETUP                                                            28 B           15 B         1\n        dbo.DATABASELOGPARAMETERS                                                      28 B           10 B         1\n        dbo.FEATUREMANAGEMENTPARAMETERS                                                28 B           10 B         1\n        dbo.AIFSQLCTVERSION                                                            28 B           24 B         1\n        dbo.SYSHELPSETUP                                                               28 B           15 B         1\n        \n    .EXAMPLE\n        PS C:\\> Get-D365BacpacTable -Path \"c:\\Temp\\AxDB.bacpac\" -SortSizeDesc\n        \n        This will return all tables from inside the bacpac file, sorted by the original size, descending.\n        \n        It uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\n        It uses the default value \"*\" as the Table parameter, to output all tables.\n        It uses the default value \"[int]::max\" as the Top parameter, to output all tables.\n        It uses the SortSizeDesc parameter, which is by original size descending.\n        \n        A result set example:\n        \n        Name                                                                   OriginalSize CompressedSize BulkFiles\n        ----                                                                   ------------ -------------- ---------\n        dbo.TSTIMESHEETLINESTAGING                                                 35,31 GB        2,44 GB      9077\n        dbo.RESROLLUP                                                              13,30 GB      367,19 MB      3450\n        dbo.PROJECTSTAGING                                                         11,31 GB      508,70 MB      2929\n        dbo.TSTIMESHEETTABLESTAGING                                                 5,93 GB      246,65 MB      1564\n        dbo.BATCHHISTORY                                                            5,80 GB      234,99 MB      1529\n        dbo.HCMPOSITIONHIERARCHYSTAGING                                             5,16 GB      222,18 MB      1358\n        dbo.ERLCSFILEASSETTABLE                                                     3,15 GB      217,68 MB       302\n        dbo.EVENTINBOX                                                              2,92 GB      105,63 MB       747\n        dbo.HCMPOSITIONV2STAGING                                                    2,79 GB      200,27 MB       755\n        dbo.HCMEMPLOYEESTAGING                                                      2,49 GB      218,69 MB       677\n        \n    .EXAMPLE\n        PS C:\\> Get-D365BacpacTable -Path \"c:\\Temp\\AxDB.bacpac\" -SortSizeDesc -Top 5\n        \n        This will return all tables from inside the bacpac file, sorted by the original size, descending.\n        \n        It uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\n        It uses the default value \"*\" as the Table parameter, to output all tables.\n        It uses the value 5 as the Top parameter, to output only 5 tables, based on the sorting selected.\n        It uses the SortSizeDesc parameter, which is by original size descending.\n        \n        A result set example:\n        \n        Name                                                                   OriginalSize CompressedSize BulkFiles\n        ----                                                                   ------------ -------------- ---------\n        dbo.TSTIMESHEETLINESTAGING                                                 35,31 GB        2,44 GB      9077\n        dbo.RESROLLUP                                                              13,30 GB      367,19 MB      3450\n        dbo.PROJECTSTAGING                                                         11,31 GB      508,70 MB      2929\n        dbo.TSTIMESHEETTABLESTAGING                                                 5,93 GB      246,65 MB      1564\n        dbo.BATCHHISTORY                                                            5,80 GB      234,99 MB      1529\n        \n    .EXAMPLE\n        PS C:\\> Get-D365BacpacTable -Path \"c:\\Temp\\AxDB.bacpac\" -Table \"Sales*\"\n        \n        This will return all tables which matches the \"Sales*\" wildcard search from inside the bacpac file.\n        \n        It uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\n        It uses the default value \"Sales*\" as the Table parameter, to output all tables that matches the wildcard pattern.\n        It uses the default value \"[int]::max\" as the Top parameter, to output all tables.\n        It uses the default sort, which is by name acsending.\n        \n        A result set example:\n        \n        Name                                                                   OriginalSize CompressedSize BulkFiles\n        ----                                                                   ------------ -------------- ---------\n        dbo.SALESPARAMETERS                                                         4,29 KB          310 B         1\n        dbo.SALESPARMUPDATE                                                       273,48 KB       24,21 KB         1\n        dbo.SALESQUOTATIONTOLINEPARAMETERS                                          4,18 KB          596 B         1\n        dbo.SALESSUMMARYPARAMETERS                                                  2,95 KB          425 B         1\n        dbo.SALESTABLE                                                              1,20 KB          313 B         1\n        dbo.SALESTABLE_W                                                              224 B           60 B         1\n        dbo.SALESTABLE2LINEPARAMETERS                                               4,46 KB          637 B         1\n        \n    .EXAMPLE\n        PS C:\\> Get-D365BacpacTable -Path \"c:\\Temp\\AxDB.bacpac\" -Table \"Sales*\",\"CUSTINVOICE*\"\n        \n        This will return all tables which matches the \"Sales*\" and \"CUSTINVOICE*\" wildcard searches from inside the bacpac file.\n        \n        It uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\n        It uses the default value \"Sales*\" and \"CUSTINVOICE*\" as the Table parameter, to output all tables that matches the wildcard pattern.\n        It uses the default value \"[int]::max\" as the Top parameter, to output all tables.\n        It uses the default sort, which is by name acsending.\n        \n        A result set example:\n        \n        Name                                                                   OriginalSize CompressedSize BulkFiles\n        ----                                                                   ------------ -------------- ---------\n        dbo.CUSTINVOICEJOUR                                                         2,01 MB      118,87 KB         1\n        dbo.CUSTINVOICELINE                                                        14,64 MB      975,30 KB         4\n        dbo.CUSTINVOICELINEINTERPROJ                                                6,58 MB      477,97 KB         2\n        dbo.CUSTINVOICETABLE                                                        1,06 MB       56,56 KB         1\n        dbo.CUSTINVOICETRANS                                                       32,34 MB        1,51 MB        54\n        dbo.SALESPARAMETERS                                                         4,29 KB          310 B         1\n        dbo.SALESPARMUPDATE                                                       273,48 KB       24,21 KB         1\n        dbo.SALESQUOTATIONTOLINEPARAMETERS                                          4,18 KB          596 B         1\n        dbo.SALESSUMMARYPARAMETERS                                                  2,95 KB          425 B         1\n        dbo.SALESTABLE                                                              1,20 KB          313 B         1\n        dbo.SALESTABLE_W                                                              224 B           60 B         1\n        dbo.SALESTABLE2LINEPARAMETERS                                               4,46 KB          637 B         1\n        \n    .EXAMPLE\n        PS C:\\> Get-D365BacpacTable -Path \"c:\\Temp\\AxDB.bacpac\" -Table \"SalesTable\",\"CustTable\"\n        \n        This will return the tables \"dbo.SalesTable\" and \"dbo.CustTable\" from inside the bacpac file.\n        \n        It uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\n        It uses the default value \"SalesTable\" and \"CustTable\" as the Table parameter, to output the tables that matches the names.\n        It uses the default value \"[int]::max\" as the Top parameter, to output all tables.\n        It uses the default sort, which is by name acsending.\n        \n        A result set example:\n        \n        Name                                                                   OriginalSize CompressedSize BulkFiles\n        ----                                                                   ------------ -------------- ---------\n        dbo.CUSTTABLE                                                             154,91 KB        8,26 KB         1\n        dbo.SALESTABLE                                                              1,20 KB          313 B         1\n        \n    .NOTES\n        Tags: Bacpac, Servicing, Data, SqlPackage, Table, Size, Troubleshooting\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-D365BacpacTable {\n    [CmdletBinding(DefaultParameterSetName = \"Default\")]\n    param (\n        [Parameter(Mandatory = $true)]\n        [Alias('File')]\n        [Alias('BacpacFile')]\n        [string] $Path,\n\n        [string[]] $Table = \"*\",\n\n        [int] $Top = [int]::MaxValue,\n\n        [Parameter(ParameterSetName = \"SortSizeAsc\")]\n        [switch] $SortSizeAsc,\n\n        [Parameter(ParameterSetName = \"SortSizeDesc\")]\n        [switch] $SortSizeDesc\n\n    )\n    \n    begin {\n        if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        $file = [System.IO.File]::Open($Path, [System.IO.FileMode]::Open)\n\n        $zipArch = [System.IO.Compression.ZipArchive]::new($file)\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n\n        $bulkFilesArray = New-Object System.Collections.Generic.List[System.Object]\n\n        foreach ($item in $table) {\n\n            $fullTableName = \"\"\n\n            if ($item -eq \"*\") {\n                $fullTableName = $item\n            }\n            elseif (-not ($item -like \"*.*\")) {\n                $fullTableName = \"dbo.$item\"\n            }\n            else {\n                $fullTableName = $item\n            }\n            \n            Write-PSFMessage -Level Verbose -Message \"Looking for $fullTableName.\"\n\n            $entries = $zipArch.Entries | Where-Object Fullname -like \"Data/$fullTableName/*\"\n\n            $bulkFilesArray.AddRange(@($($entries | Select-Object -Property *, @{Name = \"Table\"; Expression = { $_.FullName.Split(\"/\")[1] } })))\n        }\n\n        $bulkFiles = $bulkFilesArray.ToArray() | Sort-Object -Property Fullname -Unique\n\n        $grouped = $bulkFiles | Group-Object -Property Table\n\n        $res = $grouped | ForEach-Object {\n            [pscustomobject]@{ Name = $_.Name\n                OriginalSize        = [PSFSize]$($_.Group.Length | Measure-Object -sum | Select-Object -ExpandProperty sum)\n                CompressedSize      = [PSFSize]$($_.Group.CompressedLength | Measure-Object -sum | Select-Object -ExpandProperty sum)\n                BulkFiles           = $_.Count\n                PSTypeName          = 'D365FO.TOOLS.Bacpac.Table'\n            }\n        }\n\n        if ($SortSizeAsc) {\n            $res | Sort-Object OriginalSize | Select-Object -First $Top\n        }\n        elseif ($SortSizeDesc) {\n            $res | Sort-Object OriginalSize -Descending | Select-Object -First $Top\n        }\n        else {\n            $res | Sort-Object Name | Select-Object -First $Top\n        }\n    }\n    \n    end {\n        if ($zipArch) {\n            $bulkFilesArray.Clear()\n            $bulkFilesArray = $null\n            $zipArch.Dispose()\n        }\n\n        if ($file) {\n            $file.Close()\n            $file.Dispose()\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365broadcastmessage.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get broadcast message from the D365FO environment\n        \n    .DESCRIPTION\n        Get broadcast message from the D365FO environment by looking into the database table\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER ExcludeExpired\n        Exclude all the records that has already expired\n        \n    .EXAMPLE\n        PS C:\\> Get-D365BroadcastMessage\n        \n        This will display all the broadcast message records from the SysBroadcastMessage table.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365BroadcastMessage -ExcludeExpired\n        \n        This will display all active the broadcast message records from the SysBroadcastMessage table.\n        \n    .NOTES\n        Tags: Broadcast, Message, SysBroadcastMessage, Servicing, Message, Users, Environment\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Get-D365BroadcastMessage {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [Parameter(Mandatory = $false, Position = 1)]\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Mandatory = $false, Position = 2)]\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false, Position = 3)]\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false, Position = 4)]\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [switch] $ExcludeExpired\n    )\n\n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n    $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd\n    }\n\n    $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n\n    if ($ExcludeExpired) {\n        $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\get-broadcastmessageactive.sql\") -join [Environment]::NewLine\n    }\n    else {\n        $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\get-broadcastmessage.sql\") -join [Environment]::NewLine\n    }\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n    \n        $reader = $sqlCommand.ExecuteReader()\n\n        while ($reader.Read() -eq $true) {\n            [PSCustomObject]@{\n                StartTime    = [System.TimeZoneInfo]::ConvertTimeFromUtc($($reader.GetDateTime($($reader.GetOrdinal(\"FROMDATETIME\")))), [System.TimeZoneInfo]::Local)\n                EndTime      = [System.TimeZoneInfo]::ConvertTimeFromUtc($($reader.GetDateTime($($reader.GetOrdinal(\"TODATETIME\")))), [System.TimeZoneInfo]::Local)\n                StartTimeUtc = [System.TimeZoneInfo]::ConvertTimeFromUtc($($reader.GetDateTime($($reader.GetOrdinal(\"TODATETIME\")))), [System.TimeZoneInfo]::Utc)\n                EndTimeUtc   = [System.TimeZoneInfo]::ConvertTimeFromUtc($($reader.GetDateTime($($reader.GetOrdinal(\"TODATETIME\")))), [System.TimeZoneInfo]::Utc)\n                AOSId        = \"$($reader.GetString($($reader.GetOrdinal(\"AOSID\"))))\"\n            }\n        }\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n    finally {\n        $reader.close()\n\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365broadcastmessageconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get broadcast message configs\n        \n    .DESCRIPTION\n        Get all broadcast message configuration objects from the configuration store\n        \n    .PARAMETER Name\n        The name of the broadcast message configuration you are looking for\n        \n        Default value is \"*\" to display all broadcast message configs\n        \n    .PARAMETER OutputAsHashtable\n        Instruct the cmdlet to return a hastable object\n        \n    .EXAMPLE\n        PS C:\\> Get-D365BroadcastMessageConfig\n        \n        This will display all broadcast message configurations on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365BroadcastMessageConfig -OutputAsHashtable\n        \n        This will display all broadcast message configurations on the machine.\n        Every object will be output as a hashtable, for you to utilize as parameters for other cmdlets.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365BroadcastMessageConfig -Name \"UAT\"\n        \n        This will display the broadcast message configuration that is saved with the name \"UAT\" on the machine.\n        \n    .NOTES\n        Tags: Servicing, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n    .LINK\n        Add-D365BroadcastMessageConfig\n        \n    .LINK\n        Clear-D365ActiveBroadcastMessageConfig\n        \n    .LINK\n        Get-D365ActiveBroadcastMessageConfig\n        \n    .LINK\n        Remove-D365BroadcastMessageConfig\n        \n    .LINK\n        Send-D365BroadcastMessage\n        \n    .LINK\n        Set-D365ActiveBroadcastMessageConfig\n#>\n\nfunction Get-D365BroadcastMessageConfig {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')]\n    [CmdletBinding()]\n    [OutputType('PSCustomObject')]\n    param (\n        [string] $Name = \"*\",\n\n        [switch] $OutputAsHashtable\n    )\n    \n    Write-PSFMessage -Level Verbose -Message \"Fetch all configurations based on $Name\" -Target $Name\n\n    $Name = $Name.ToLower()\n    $configurations = Get-PSFConfig -FullName \"d365fo.tools.broadcast.$Name.name\"\n\n    foreach ($configName in $configurations.Value.ToLower()) {\n        Write-PSFMessage -Level Verbose -Message \"Working against the $configName configuration\" -Target $configName\n        $res = @{}\n\n        $configName = $configName.ToLower()\n\n        foreach ($config in Get-PSFConfig -FullName \"d365fo.tools.broadcast.$configName.*\") {\n            $propertyName = $config.FullName.ToString().Replace(\"d365fo.tools.broadcast.$configName.\", \"\")\n            $res.$propertyName = $config.Value\n        }\n        \n        if($OutputAsHashtable) {\n            $res\n        } else {\n            [PSCustomObject]$res\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365clickoncetrustprompt.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the ClickOnce configuration\n        \n    .DESCRIPTION\n        Creates the needed registry keys and values for ClickOnce to work on the machine\n        \n    .EXAMPLE\n        PS C:\\> Get-D365ClickOnceTrustPrompt\n        \n        This will get the current ClickOnce configuration\n        \n    .NOTES\n        Tags: ClickOnce, Registry, TrustPrompt\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Get-D365ClickOnceTrustPrompt {\n    [CmdletBinding()]\n    param (\n    \n    )\n    \n    begin {\n    }\n    \n    process {\n        Write-PSFMessage -Level Verbose -Message \"Testing if the registry key exists or not\"\n\n        if ((Test-Path -Path \"HKLM:\\SOFTWARE\\MICROSOFT\\.NETFramework\\Security\\TrustManager\\PromptingLevel\") -eq $false) {\n            Write-PSFMessage -Level Host -Message \"It looks like ClickOnce trust prompt has never been configured on this machine. Run Set-D365ClickOnceTrustPrompt to fix that\"\n        }\n        else {\n            Write-PSFMessage -Level Verbose -Message \"Gathering the details from registry\"\n\n            [PSCustomObject]@{\n                UntrustedSites = (Get-ItemProperty -Path \"HKLM:\\SOFTWARE\\MICROSOFT\\.NETFramework\\Security\\TrustManager\\PromptingLevel\" \"UntrustedSites\").UntrustedSites\n                Internet       = (Get-ItemProperty -Path \"HKLM:\\SOFTWARE\\MICROSOFT\\.NETFramework\\Security\\TrustManager\\PromptingLevel\" \"Internet\").Internet\n                MyComputer     = (Get-ItemProperty -Path \"HKLM:\\SOFTWARE\\MICROSOFT\\.NETFramework\\Security\\TrustManager\\PromptingLevel\" \"MyComputer\").MyComputer\n                LocalIntranet  = (Get-ItemProperty -Path \"HKLM:\\SOFTWARE\\MICROSOFT\\.NETFramework\\Security\\TrustManager\\PromptingLevel\" \"LocalIntranet\").LocalIntranet\n                TrustedSites   = (Get-ItemProperty -Path \"HKLM:\\SOFTWARE\\MICROSOFT\\.NETFramework\\Security\\TrustManager\\PromptingLevel\" \"TrustedSites\").TrustedSites\n            }\n        }\n\n    }\n    \n    end {\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365compilerresult.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the compiler outputs presented\n        \n    .DESCRIPTION\n        Get the compiler outputs presented in a structured manner on the screen\n        \n        It could be a Visual Studio compiler log or it could be a Invoke-D365ModuleCompile log you want analyzed\n        \n    .PARAMETER Path\n        Path to the compiler log file that you want to work against\n        \n        A BuildModelResult.log or a Dynamics.AX.*.xppc.log file will both work\n        \n    .PARAMETER ErrorsOnly\n        Instructs the cmdlet to only output compile results where there was errors detected\n        \n    .PARAMETER OutputTotals\n        Instructs the cmdlet to output the total errors and warnings after the analysis\n        \n    .PARAMETER OutputAsObjects\n        Instructs the cmdlet to output the objects instead of formatting them\n        \n        If you don't assign the output, it will be formatted the same way as the original output, but without the coloring of the column values\n        \n    .EXAMPLE\n        PS C:\\> Get-D365CompilerResult -Path \"c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log\"\n        \n        This will analyze the compiler log file for warning and errors.\n        \n        A result set example:\n        \n        File                                                                                    Warnings Errors\n        ----                                                                                    -------- ------\n        c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log                                        2      1\n        \n    .EXAMPLE\n        PS C:\\> Get-D365CompilerResult -Path \"c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log\" -ErrorsOnly\n        \n        This will analyze the compiler log file for warning and errors, but only output if it has errors.\n        \n        A result set example:\n        \n        File                                                                                    Warnings Errors\n        ----                                                                                    -------- ------\n        c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log                                        2      1\n        \n    .EXAMPLE\n        PS C:\\> Get-D365CompilerResult -Path \"c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log\" -ErrorsOnly -OutputAsObjects\n        \n        This will analyze the compiler log file for warning and errors, but only output if it has errors.\n        The output will be PSObjects, which can be assigned to a variable and used for futher analysis.\n        \n        A result set example:\n        \n        File                                                                                    Warnings Errors\n        ----                                                                                    -------- ------\n        c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log                                        2      1\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Module -Name *Custom* | Invoke-D365ModuleCompile | Get-D365CompilerResult -OutputTotals\n        \n        This will find all modules with Custom in their name.\n        It will pass thoses modules into the Invoke-D365ModuleCompile, which will compile them.\n        It will pass the paths to each compile output log to Get-D365CompilerResult, which will analyze them for warning and errors.\n        It will output the total number of warning and errors found.\n        \n        File                                                                                    Warnings Errors\n        ----                                                                                    -------- ------\n        c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log                                        2      1\n        \n        Total Errors: 1\n        Total Warnings: 2\n        \n    .NOTES\n        Tags: Compiler, Build, Errors, Warnings, Tasks\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        This cmdlet is inspired by the work of \"Vilmos Kintera\" (twitter: @DAXRunBase)\n        \n        All credits goes to him for showing how to extract these information\n        \n        His blog can be found here:\n        https://www.daxrunbase.com/blog/\n        \n        The specific blog post that we based this cmdlet on can be found here:\n        https://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/\n        \n        The github repository containing the original scrips can be found here:\n        https://github.com/DAXRunBase/PowerShell-and-Azure\n        \n#>\nfunction Get-D365CompilerResult {\n    [CmdletBinding()]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')]\n    [OutputType('[PsCustomObject]')]\n    param (\n        [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]\n        [Alias('LogFile')]\n        [string] $Path,\n\n        [switch] $ErrorsOnly,\n\n        [switch] $OutputTotals,\n\n        [switch] $OutputAsObjects\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n    \n        $outputCollection = New-Object System.Collections.Generic.List[System.Object]\n    }\n\n    process {\n        if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n        $res = Get-CompilerResult -Path $Path\n\n        if ($null -ne $res) {\n            $outputCollection.Add($res)\n        }\n    }\n\n    end {\n        \n        $totalErrors = 0\n        $totalWarnings = 0\n    \n        $resCol = @($outputCollection.ToArray())\n        \n        $totalWarnings = ($resCol | Measure-Object -Property Warnings -Sum).Sum\n        $totalErrors = ($resCol | Measure-Object -Property Errors -Sum).Sum\n\n        if($ErrorsOnly) {\n            $resCol = @($resCol | Where-Object Errors -gt 0)\n        }\n\n        if($OutputAsObjects){\n            $resCol\n        }\n        else {\n            $resCol | format-table File, @{Label = \"Warnings\"; Expression = { $e = [char]27; $color = \"93\"; \"$e[${color}m$($_.Warnings)${e}[0m\" }; Align = 'right' }, @{Label = \"Errors\"; Expression = { $e = [char]27; $color = \"91\"; \"$e[${color}m$($_.Errors)${e}[0m\" }; Align = 'right' }\n        }\n\n        if ($OutputTotals) {\n            Write-PSFHostColor -String \"<c='Red'>Total Errors: $totalErrors</c>\"\n            Write-PSFHostColor -String \"<c='Yellow'>Total Warnings: $totalWarnings</c>\"\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365database.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get databases from the server\n        \n    .DESCRIPTION\n        Get the names of databases on either SQL Server or in Azure SQL Database instance\n        \n    .PARAMETER Name\n        Name of the database that you are looking for\n        \n        Default value is \"*\" which will show all databases\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Database\n        \n        This will show all databases on the default SQL Server / Azure SQL Database instance.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Database -Name AXDB_ORIGINAL\n        \n        This will show if the AXDB_ORIGINAL database exists on the default SQL Server / Azure SQL Database instance.\n        \n    .NOTES\n        Tags: Database, DB, Servicing\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Get-D365Database {\n    [CmdletBinding()]\n    [OutputType('[PsCustomObject]')]\n    param (\n        [string[]] $Name = \"*\",\n\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword\n    )\n\n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n    $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = \"master\";\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd\n    }\n\n    $sqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n\n    $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\get-database.sql\") -join [Environment]::NewLine\n\n    try {\n        $sqlCommand.Connection.Open()\n    \n        $reader = $sqlCommand.ExecuteReader()\n\n        while ($reader.Read() -eq $true) {\n            $res = [PSCustomObject]@{\n                Name             = \"$($reader.GetString($($reader.GetOrdinal(\"NAME\"))))\"\n            }\n\n            if ($res.Name -NotLike $Name) { continue }\n\n            $res\n        }\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n    finally {\n        $reader.close()\n\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365databaseaccess.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Shows the Database Access information for the D365 Environment\n        \n    .DESCRIPTION\n        Gets all database information from the D365 environment\n        \n    .EXAMPLE\n        PS C:\\> Get-D365DatabaseAccess\n        \n        This will get all relevant details, including connection details, for the database configured for the environment\n        \n    .NOTES\n        Tags: Database, Connection, Sql, SqlUser, SqlPwd\n        \n        Author: Rasmus Andersen (@ITRasmus)\n        \n        The cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations.\n        The call to the dll file gets all relevant connections details for the database server.\n        \n#>\nfunction Get-D365DatabaseAccess {\n    [CmdletBinding()]\n    param ()\n\n    $environment = Get-ApplicationEnvironment\n    \n    return $environment.DataAccess\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365decryptedwebconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Decrypts the AOS config file\n        \n    .DESCRIPTION\n        Function used for decrypting the config file used by the D365 Finance & Operations AOS service\n        \n    .PARAMETER OutputPath\n        Place where the decrypted files should be placed\n        \n        Default value is: \"c:\\temp\\d365fo.tools\\WebConfigDecrypted\"\n        \n    .PARAMETER AosServiceWebRootPath\n        Location of the D365 webroot folder\n        \n    .EXAMPLE\n        PS C:\\> Get-D365DecryptedWebConfig\n        \n        This will get the config file from the instance, decrypt it and save it.\n        IT will save the decrypted web.config file in the default location: \"c:\\temp\\d365fo.tools\\WebConfigDecrypted\".\n        \n        A result set example:\n        \n        Filename   LastModified        File\n        --------   ------------        ----\n        web.config 7/1/2021 9:01:31 PM C:\\temp\\d365fo.tools\\WebConfigDecrypted\\web.config\n        \n    .EXAMPLE\n        PS C:\\> Get-D365DecryptedWebConfig -OutputPath \"c:\\temp\\d365fo.tools\"\n        \n        This will get the config file from the instance, decrypt it and save it to \"c:\\temp\\d365fo.tools\"\n        \n        A result set example:\n        \n        Filename   LastModified        File\n        --------   ------------        ----\n        web.config 7/1/2021 9:07:36 PM C:\\temp\\d365fo.tools\\web.config\n        \n    .NOTES\n        Tags: Configuration, Service Account, Sql, SqlUser, SqlPwd, WebConfig, Web.Config, Decryption\n        \n        Author : Rasmus Andersen (@ITRasmus)\n        Author : Mötz Jensen (@splaxi)\n        \n        Used for getting the Password for the database and other service accounts used in environment\n#>\nfunction Get-D365DecryptedWebConfig {\n    [Alias(\"Get-D365DecryptedConfigFile\")]\n    param(\n        [string] $OutputPath = \"c:\\temp\\d365fo.tools\\WebConfigDecrypted\",\n\n        [string] $AosServiceWebRootPath = $Script:AOSPath\n    )\n\n    $WebConfigFile = Join-Path $AosServiceWebRootPath $Script:WebConfig\n\n    if (!(Test-PathExists -Path $WebConfigFile -Type Leaf)) { return }\n    if (!(Test-PathExists -Path $OutputPath -Type Container -Create)) { return }\n\n    Write-PSFMessage -Level Verbose -Message \"Starting the decryption logic\"\n    New-DecryptedFile $WebConfigFile $OutputPath\n\n    $file = Get-Item -Path \"$OutputPath\\web.config\" -ErrorAction SilentlyContinue\n\n    if ($null -eq $file) {\n        $messageString = \"There was an error while decrypting the <c='em'>web.config</c> file.\"\n        Write-PSFMessage -Level Host -Message $messageString\n        Stop-PSFFunction -Message \"Stopping because the web.config file wasn't decrypted.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', '')))\n        return\n    }\n    \n    $file | Select-PSFObject \"Name as Filename\", \"LastWriteTime as LastModified\", \"Fullname as File\"\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365defaultmodelfornewprojects.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the default model used creating new projects in Visual Studio\n        \n    .DESCRIPTION\n        Get the registered default model that is used across all new projects that are created inside Visual Studio when working with D365FO project types\n        \n    .EXAMPLE\n        PS C:\\> Get-D365DefaultModelForNewProjects\n        \n        This will display the current default module registered in the \"DynamicsDevConfig.xml\" file.\n        Located in Documents\\Visual Studio Dynamics 365\\ or in Documents\\Visual Studio 2015\\Settings\\ depending on the version.\n        \n    .NOTES\n        Tag: Model, Models, Development, Default Model, Module, Project\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        The work for this cmdlet / function was inspired by Robin Kretzschmar (@DarkSmile92) blog post about changing the default model.\n        \n        The direct link for his blog post is: https://robscode.onl/d365-set-default-model-for-new-projects/\n        \n        His main blog can found here: https://robscode.onl/\n        \n#>\n\nfunction Get-D365DefaultModelForNewProjects {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    param ()\n\n    $filePath = \"$env:UserProfile\\Documents\\Visual Studio Dynamics 365\\DynamicsDevConfig.xml\"\n    if (-not (Test-PathExists -Path $filePath -Type Leaf)) {\n        $filePath = \"$env:UserProfile\\Documents\\Visual Studio 2015\\Settings\\DynamicsDevConfig.xml\"\n    }\n    if (-not (Test-PathExists -Path $filePath -Type Leaf)) { return }\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    $namespace = @{ns = \"http://schemas.microsoft.com/dynamics/2012/03/development/configuration\" }\n    $defaultModel = Select-Xml -XPath \"/ns:DynamicsDevConfig/ns:DefaultModelForNewProjects\" -Path $filePath -Namespace $namespace\n\n    $modelName = $defaultModel.Node.InnerText\n    [PSCustomObject] @{DefaultModelForNewProjects = $modelName }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365dotnetclass.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get a .NET class from the Dynamics 365 for Finance and Operations installation\n        \n    .DESCRIPTION\n        Get a .NET class from an assembly file (dll) from the package directory\n        \n    .PARAMETER Name\n        Name of the .NET class that you are looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"ER*Excel*\"\n        \n        Default value is \"*\" which will search for all classes\n        \n    .PARAMETER Assembly\n        Name of the assembly file that you want to search for the .NET class\n        \n        Accepts wildcards for searching. E.g. -Name \"*AX*Framework*.dll\"\n        \n        Default value is \"*.dll\" which will search for assembly files\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed packages\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Get-D365DotNetClass -Name \"ERText*\"\n        \n        Will search across all assembly files (*.dll) that are located in the default package directory after\n        any class that fits the search \"ERText*\"\n        \n    .EXAMPLE\n        PS C:\\> Get-D365DotNetClass -Name \"ERText*\" -Assembly \"*LocalizationFrameworkForAx.dll*\"\n        \n        Will search across all assembly files (*.dll) that are fits the search \"*LocalizationFrameworkForAx.dll*\",\n        that are located in the default package directory, after any class that fits the search \"ERText*\"\n        \n    .EXAMPLE\n        PS C:\\> Get-D365DotNetClass -Name \"ERText*\" | Export-Csv -Path c:\\temp\\results.txt -Delimiter \";\"\n        \n        Will search across all assembly files (*.dll) that are located in the default package directory after\n        any class that fits the search \"ERText*\"\n        \n        The output is saved to a file to make it easier to search inside the result set\n        \n    .NOTES\n        Tags: .Net, DotNet, Class, Development\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages.\n        \n#>\nfunction Get-D365DotNetClass {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )]\n        [string] $Name = \"*\",\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )]\n        [string] $Assembly = \"*.dll\",\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 3 )]\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n    \n    begin {\n    }\n    \n    process {\n        Invoke-TimeSignal -Start\n\n        $files = (Get-ChildItem -Path $PackageDirectory -Filter $Assembly -Recurse -Exclude \"*Resources*\" | Where-Object Fullname -Notlike \"*Resources*\" )\n\n        $files | ForEach-Object {\n            $path = $_.Fullname\n            try {\n                Write-PSFMessage -Level Verbose -Message \"Loading the dll file: $path\" -Target $path\n                \n                [Reflection.Assembly]$ass = [Reflection.Assembly]::LoadFile($path)\n\n                $res = $ass.GetTypes()\n\n                Write-PSFMessage -Level Verbose -Message \"Looping through all types from the assembly\"\n                foreach ($obj in $res) {\n                    if ($obj.Name -NotLike $Name) { continue }\n                    [PSCustomObject]@{\n                        IsPublic = $obj.IsPublic\n                        IsSerial = $obj.IsSerial\n                        Name     = $obj.Name\n                        BaseType = $obj.BaseType\n                        File     = $path\n                    }\n                }\n            }\n            catch {\n                Write-PSFMessage -Level Host -Message \"Something went wrong while trying to load the path: $path\" -Exception $PSItem.Exception\n                Stop-PSFFunction -Message \"Stopping because of errors\"\n                return\n            }\n        }\n\n        Invoke-TimeSignal -End\n    }\n\n    end {\n    }\n\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365dotnetmethod.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get a .NET method from the Dynamics 365 for Finance and Operations installation\n        \n    .DESCRIPTION\n        Get a .NET method from an assembly file (dll) from the package directory\n        \n    .PARAMETER Assembly\n        Name of the assembly file that you want to search for the .NET method\n        \n        Provide the full path for the assembly file you want to work against\n        \n    .PARAMETER Name\n        Name of the .NET method that you are looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"parmER*Excel*\"\n        \n        Default value is \"*\" which will search for all methods\n        \n    .PARAMETER TypeName\n        Name of the .NET class that you want to work against\n        \n        Accepts wildcards for searching. E.g. -Name \"*ER*Excel*\"\n        \n        Default value is \"*\" which will work against all classes\n        \n    .EXAMPLE\n        PS C:\\> Get-D365DotNetMethod -Assembly \"C:\\AOSService\\PackagesLocalDirectory\\ElectronicReporting\\bin\\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll\"\n        \n        Will get all methods, across all classes, from the assembly file\n        \n    .EXAMPLE\n        PS C:\\> Get-D365DotNetMethod -Assembly \"C:\\AOSService\\PackagesLocalDirectory\\ElectronicReporting\\bin\\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll\" -TypeName \"ERTextFormatExcelFileComponent\"\n        \n        Will get all methods, from the \"ERTextFormatExcelFileComponent\" class, from the assembly file\n        \n    .EXAMPLE\n        PS C:\\> Get-D365DotNetMethod -Assembly \"C:\\AOSService\\PackagesLocalDirectory\\ElectronicReporting\\bin\\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll\" -TypeName \"ERTextFormatExcelFileComponent\" -Name \"*parm*\"\n        \n        Will get all methods that fits the search \"*parm*\", from the \"ERTextFormatExcelFileComponent\" class, from the assembly file\n        \n    .EXAMPLE\n        PS C:\\> Get-D365DotNetClass -Name \"ERTextFormatExcelFileComponent\" -Assembly \"*LocalizationFrameworkForAx.dll*\" | Get-D365DotNetMethod\n        \n        Will get all methods, from the \"ERTextFormatExcelFileComponent\" class, from any assembly file that fits the search \"*LocalizationFrameworkForAx.dll*\"\n        \n    .NOTES\n        Tags: .Net, DotNet, Class, Method, Methods, Development\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages.\n        \n#>\nfunction Get-D365DotNetMethod {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 1 )]\n        [Alias('File')]\n        [string] $Assembly,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )]\n        [Alias('MethodName')]\n        [string] $Name = \"*\",\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 3 )]\n        [Alias('ClassName')]\n        [string] $TypeName = \"*\"\n\n    )\n    \n    begin {\n    }\n    \n    process {\n        Invoke-TimeSignal -Start\n\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Loading the file\" -Target $Assembly\n            [Reflection.Assembly]$ass = [Reflection.Assembly]::LoadFile($Assembly)\n\n            $types = $ass.GetTypes()\n\n            foreach ($obj in $types) {\n                Write-PSFMessage -Level Verbose -Message \"Type name loaded\" -Target $obj.Name\n\n                if ($obj.Name -NotLike $TypeName) {continue}\n\n                $members = $obj.GetMethods()\n\n                foreach ($objI in $members) {\n                    if ($objI.Name -NotLike $Name) { continue }\n                    [PSCustomObject]@{\n                        TypeName     = $obj.Name\n                        TypeIsPublic = $obj.IsPublic\n                        MethodName   = $objI.Name\n                    }\n\n                }\n            }\n        }\n        catch {\n            Write-PSFMessage -Level Warning -Message \"Something went wrong while working on: $Assembly\" -ErrorRecord $_\n        }\n        \n        Invoke-TimeSignal -End\n    }\n\n    end {\n    }\n\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365environment.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Cmdlet to get the current status for the different services in a Dynamics 365 Finance & Operations environment\n        \n    .DESCRIPTION\n        List status for all relevant services that is running in a D365FO environment\n        \n    .PARAMETER ComputerName\n        An array of computers that you want to query for the services status on.\n        \n    .PARAMETER All\n        Set when you want to query all relevant services\n        \n        Includes:\n        Aos\n        Batch\n        Financial Reporter\n        DMF\n        \n    .PARAMETER Aos\n        Instruct the cmdlet to query the AOS (IIS) service\n        \n    .PARAMETER Batch\n        Instruct the cmdlet query the batch service\n        \n    .PARAMETER FinancialReporter\n        Instruct the cmdlet query the financial reporter (Management Reporter 2012)\n        \n    .PARAMETER DMF\n        Instruct the cmdlet query the DMF service\n        \n    .PARAMETER OnlyStartTypeAutomatic\n        Instruct the cmdlet to filter out services that are set to manual start or disabled\n        \n    .PARAMETER OutputServiceDetailsOnly\n        Instruct the cmdlet to exclude the server name from the output\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Environment\n        \n        Will query all D365FO service on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Environment -All\n        \n        Will query all D365FO service on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Environment -OnlyStartTypeAutomatic\n        \n        Will query all D365FO service on the machine.\n        It will filter out all services that are either configured as manual or disabled.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Environment -ComputerName \"TEST-SB-AOS1\",\"TEST-SB-AOS2\",\"TEST-SB-BI1\" -All\n        \n        Will query all D365FO service on the different machines.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Environment -Aos -Batch\n        \n        Will query the Aos & Batch services on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Environment -FinancialReporter -DMF\n        \n        Will query the FinancialReporter & DMF services on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Environment -OutputServiceDetailsOnly\n        \n        Will query all D365FO service on the machine.\n        Will omit the servername from the output.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Environment -FinancialReporter | Set-Service -StartupType Manual\n        \n        This will configure the Financial Reporter services to be start type manual.\n        \n    .NOTES\n        Tags: Environment, Service, Services, Aos, Batch, Servicing\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-D365Environment {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidDefaultValueSwitchParameter\", \"\")]\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    \n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 1 )]\n        [string[]] $ComputerName = @($env:computername),\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default')]\n        [switch] $All = $true,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific')]\n        [switch] $Aos,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific')]\n        [switch] $Batch,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific')]\n        [switch] $FinancialReporter,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific')]\n        [switch] $DMF,\n\n        [switch] $OnlyStartTypeAutomatic,\n\n        [switch] $OutputServiceDetailsOnly\n    )\n\n    if ($PSCmdlet.ParameterSetName -eq \"Specific\") {\n        $All = $false\n    }\n\n    if ( (-not ($All)) -and (-not ($Aos)) -and (-not ($Batch)) -and (-not ($FinancialReporter)) -and (-not ($DMF))) {\n        Write-PSFMessage -Level Host -Message \"You have to use at least one switch when running this cmdlet. Please run the cmdlet again.\"\n        Stop-PSFFunction -Message \"Stopping because of missing parameters\"\n        return\n    }\n\n    $Params = Get-DeepClone $PSBoundParameters\n    if($Params.ContainsKey(\"ComputerName\")){$null = $Params.Remove(\"ComputerName\")}\n    if($Params.ContainsKey(\"OutputServiceDetailsOnly\")){$null = $Params.Remove(\"OutputServiceDetailsOnly\")}\n    if($Params.ContainsKey(\"OnlyStartTypeAutomatic\")){$null = $Params.Remove(\"OnlyStartTypeAutomatic\")}\n\n    $Services = Get-ServiceList @Params\n\n    $Results = foreach ($server in $ComputerName) {\n        Get-Service -ComputerName $server -Name $Services -ErrorAction SilentlyContinue | Select-Object @{Name = \"Server\"; Expression = {$Server}}, Name, Status, StartType, DisplayName\n    }\n    \n    $outputTypeName = \"D365FO.TOOLS.Environment.Service\"\n\n    if($OutputServiceDetailsOnly) {\n        $outputTypeName = \"D365FO.TOOLS.Environment.Service.Minimal\"\n    }\n\n    if($OnlyStartTypeAutomatic){\n        $Results = $Results | Where-Object StartType -eq \"Automatic\"\n    }\n\n    $Results | Select-PSFObject -TypeName $outputTypeName Server, DisplayName, Status, StartType, Name\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365environmentsettings.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the D365FO environment settings\n        \n    .DESCRIPTION\n        Gets all settings the Dynamics 365 for Finance & Operations environment uses.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365EnvironmentSettings\n        \n        This will get all details available for the environment\n        \n    .EXAMPLE\n        PS C:\\> Get-D365EnvironmentSettings | Format-Custom -Property *\n        \n        This will get all details available for the environment and format it to show all details in a long custom object.\n        \n    .NOTES\n        Tags: Environment, Configuration, WebConfig, Web.Config, Decryption\n        \n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n        The cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations.\n        The call to the dll file gets all relevant details for the installation.\n#>\nfunction Get-D365EnvironmentSettings {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    param ()\n\n    Get-ApplicationEnvironment\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365eventtraceprovider.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get D365FO Event Trace Provider\n        \n    .DESCRIPTION\n        Get the full list of available Event Trace Providers for Dynamics 365 for Finance and Operations\n        \n    .PARAMETER Name\n        Name of the provider that you are looking for\n        \n        Default value is \"*\" to show all Event Trace Providers\n        \n        Accepts an array of names, and will automatically add wildcard searching characters for each entry\n        \n    .EXAMPLE\n        PS C:\\> Get-D365EventTraceProvider\n        \n        Will list all available Event Trace Providers on a D365FO server.\n        It will use the default option for the \"Name\" parameter.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365EventTraceProvider -Name Tax\n        \n        Will list all available Event Trace Providers on a D365FO server which contains the keyvword \"Tax\".\n        It will use the Name parameter value \"Tax\" while searching for Event Trace Providers.\n        \n        \n    .EXAMPLE\n        PS C:\\> Get-D365EventTraceProvider -Name Tax,MR\n        \n        Will list all available Event Trace Providers on a D365FO server which contains the keyvword \"Tax\" or \"MR\".\n        It will use the Name parameter array value (\"Tax\",\"MR\") while searching for Event Trace Providers.\n        \n    .NOTES\n        Tags: ETL, EventTracing, EventTrace\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        This cmdlet/function was inspired by the work of Michael Stashwick (@D365Stuff)\n        \n        He blog is located here: https://www.d365stuff.co/\n        \n        and the blogpost that pointed us in the right direction is located here: https://www.d365stuff.co/trace-batch-jobs-and-more-via-cmd-logman/\n#>\n\nfunction Get-D365EventTraceProvider {\n    [CmdletBinding()]\n    param (\n        [string[]] $Name = @(\"*\")\n    )\n    \n    begin{\n        $providers = Get-NetEventProvider -ShowInstalled | Where-Object name -like \"Microsoft-Dynamics*\" | Sort-Object name\n    }\n\n    process {\n        foreach ($searchName in $Name) {\n            $providers | Where-Object name -Like \"*$searchName*\" | Select-PSFObject \"Name as ProviderName\"\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365externalip.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the external IP address\n        \n    .DESCRIPTION\n        Get the external IP address by calling an external webpage and interpret the result from that\n        \n    .PARAMETER SaveToClipboard\n        Instruct the cmdlet to copy the IP address directly into the clipboard, to save you the trouble\n        \n    .EXAMPLE\n        PS C:\\> Get-D365ExternalIP\n        \n        Will call the external page, interpret the output and display it as output.\n        \n        A result set example:\n        \n        IpAddress\n        ---------\n        40.113.130.229\n        \n    .EXAMPLE\n        PS C:\\> Get-D365ExternalIP -SaveToClipboard\n        \n        Will call the external page, interpret the output and display it as output.\n        It will save/copy the IP address into the clipboard.\n        \n        A result set example:\n        \n        IpAddress\n        ---------\n        40.113.130.229\n        \n    .NOTES\n        Tags: DEV, Tier2, DB, Database, Debug, JIT, LCS, Azure DB, IP\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-D365ExternalIP {\n    [CmdletBinding()]\n    param (\n        [switch] $SaveToClipboard\n    )\n    \n    begin {\n        \n    }\n    \n    process {\n        $res = [PSCustomObject]@{\"IpAddress\" = (Invoke-WebRequest -Uri \"https://ifconfig.me/ip\").Content }\n\n        if ($SaveToClipboard) {\n            $res.IpAddress | Set-Clipboard\n        }\n\n        $res\n    }\n    \n    end {\n        \n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365flight.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Used to get a flight\n        \n    .DESCRIPTION\n        Provides a method for listing a flight in D365FO.\n        \n    .PARAMETER FlightName\n        Name of the flight that you are looking for\n        \n        Supports wildcards \"*\"\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Flight\n        \n        This will list all flights that are configured on the environment.\n        It will show the name and the enabled status.\n        \n        A result set example:\n        \n        FlightName                         Enabled FlightServiceId\n        ----------                         ------- ---------------\n        WHSWorkCancelForcedFlight          1       12719367\n        TAMRebateGlobalEnableFeature       1       12719367\n        EnablePerfInfoSimpleLoggerV2       1       12719367\n        EnablePerfInfoLogODataV2           1       12719367\n        EnablePerfInfoLogEtwRequestTableV2 1       12719367\n        EnablePerfInfoCursorLayerV2        1       12719367\n        EnablePerfInfoFormEngineLayerV2    1       12719367\n        EnablePerfInfoMutexWaitLayerV2     1       12719367\n        EnablePerfInfoSecurityLayerV2      1       12719367\n        EnablePerfInfoSessionLayerV2       1       12719367\n        EnablePerfInfoSQLLayerV2           1       12719367\n        EnablePerfInfoXppContainerLayerV2  1       12719367\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Flight -FlightName WHSWorkCancelForcedFlight\n        \n        This will list the flight with the specified name on the environment.\n        It will show the name and the enabled status.\n        \n        A result set example:\n        \n        FlightName                         Enabled FlightServiceId\n        ----------                         ------- ---------------\n        WHSWorkCancelForcedFlight          1       12719367\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Flight -FlightName WHS*\n        \n        This will list the flight with the specified pattern on the environment.\n        It will filter the output to match the \"WHS*\" pattern.\n        It will show the name and the enabled status.\n        \n        A result set example:\n        \n        FlightName                         Enabled FlightServiceId\n        ----------                         ------- ---------------\n        WHSWorkCancelForcedFlight          1       12719367\n        \n    .NOTES\n        Tags: Flight, Flighting\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        At no circumstances can this cmdlet be used to enable a flight in a PROD environment.\n#>\nfunction Get-D365Flight {\n    [CmdletBinding()]\n    param (\n        [String] $FlightName = \"*\",\n\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword\n    )\n\n    try {\n        $WebConfigFile = join-Path -path $Script:AOSPath $Script:WebConfig\n        Write-PSFMessage -Level Verbose -Message \"Retrieve the FlightingServiceCatalogID\" -Target $WebConfigFile\n\n        $FlightServiceNode = Select-Xml -XPath \"/configuration/appSettings/add[@key='DataAccess.FlightingServiceCatalogID']/@value\" -Path $WebConfigFile\n        $FlightServiceId = $FlightServiceNode.Node.Value\n    \n        Write-PSFMessage -Level Verbose -Message \"FlightingServiceCatalogID: $FlightServiceId\" -Target $WebConfigFile\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while reading from the web.config file\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n\n    if ($null -eq $FlightServiceId) {\n        Write-PSFMessage -Level Host -Message \"The DataAccess.FlightingServiceCatalogID setting must be set in the web.config file. See https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages#features-flighted-in-data-management-and-enabling-flighted-features for details\"\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n\n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n    $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd\n    }\n\n    $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n    $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\get-flight.sql\") -join [Environment]::NewLine\n\n    try {\n        $sqlCommand.Connection.Open()\n    \n        $reader = $sqlCommand.ExecuteReader()\n\n        while ($reader.Read() -eq $true) {\n            $res = [PSCustomObject]@{\n                FlightName      = \"$($reader.GetString($($reader.GetOrdinal(\"FLIGHTNAME\"))))\"\n                Enabled         = [System.Convert]::ToBoolean($($reader.GetInt32($($reader.GetOrdinal(\"ENABLED\")))))\n                FlightServiceId = \"$($reader.GetInt32($($reader.GetOrdinal(\"FLIGHTSERVICEID\"))))\"\n            }\n\n            if ($res.FlightName -NotLike $FlightName) { continue }\n            if ($res.FlightServiceId -NotLike $FlightServiceId) { continue }\n\n            $res\n        }\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n    finally {\n        $reader.close()\n\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365iispreload.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Gets IIS Preload status for the AOSService application pool and website.\n        \n    .DESCRIPTION\n        Returns the current IIS Preload configuration for the AOSService application:\n        - Application Pool Start Mode\n        - Idle Time-out\n        - Website Preload Enabled\n        - doAppInitAfterRestart (if Application Initialization is installed)\n        \n    .OUTPUTS\n        System.Management.Automation.PSCustomObject\n        A custom object containing the following properties:\n        - AppPool: Name of the application pool (AOSService)\n        - StartMode: Start mode of the application pool (e.g., AlwaysRunning)\n        - IdleTimeout: Idle timeout of the application pool (e.g., 00:00:00)\n        - Site: Name of the website (AOSService)\n        - PreloadEnabled: Indicates if preload is enabled for the website (True/False)\n        - DoAppInitAfterRestart: Indicates if doAppInitAfterRestart is enabled (if Application Initialization is installed)\n        - PreloadPage: The initialization page configured for preload (if any)\n        - IISApplicationInitFeature: State of the IIS Application Initialization feature (Installed/Not installed)\n        \n    .EXAMPLE\n        PS C:\\> Get-D365IISPreload\n        \n        Retrieves the IIS Preload configuration for the AOSService application pool and website.\n        \n    .NOTES\n        Author: Florian Hopfner (FH-Inway)\n        Based on Denis Trunin's article \"Enable IIS Preload to Speed Up Restart After X++ Compile\" (https://www.linkedin.com/pulse/enable-iis-preload-speed-up-restart-after-x-compile-denis-trunin-86j5c)\n        Written with GitHub Copilot GPT-4.1, mostly in agent mode. See commits for prompts.\n        \n    .LINK\n        Enable-D365IISPreload\n        \n    .LINK\n        Disable-D365IISPreload\n#>\nfunction Get-D365IISPreload {\n    [CmdletBinding()]\n    param ()\n\n    if (-not (Get-Module -ListAvailable -Name WebAdministration)) {\n        Write-PSFMessage -Level Warning -Message \"The 'WebAdministration' module is not installed. Please install it with: Install-WindowsFeature -Name Web-WebServer -IncludeManagementTools or Install-Module -Name WebAdministration -Scope CurrentUser\"\n        return\n    }\n\n    Import-Module WebAdministration -ErrorAction Stop\n\n    $iisAppInitFeature = Get-WindowsFeature -Name Web-AppInit -ErrorAction SilentlyContinue\n    $iisAppInitState = if ($iisAppInitFeature -and $iisAppInitFeature.Installed) { 'Installed' } else { 'Not installed' }\n\n    $appPool = \"AOSService\"\n    $site = \"AOSService\"\n\n    $startModeProperty = Get-ItemProperty \"IIS:\\AppPools\\$appPool\" -Name startMode\n    $startMode = $startModeProperty.Trim() # Ensure we get the value as a string without additional NoteProperty\n    $idleTimeoutValue = (Get-ItemProperty \"IIS:\\AppPools\\$appPool\" -Name processModel.idleTimeout).Value\n    $idleTimeout = if ($idleTimeoutValue -eq [TimeSpan]::Zero) { \"0\" } else { $idleTimeoutValue.ToString() }\n    $preloadEnabled = (Get-ItemProperty \"IIS:\\Sites\\$site\" -Name applicationDefaults.preloadEnabled).Value\n\n    $getDoAppInitParams = @{\n        pspath      = 'MACHINE/WEBROOT/APPHOST'\n        filter      = 'system.webServer/applicationInitialization'\n        name        = 'doAppInitAfterRestart'\n        location    = $site\n        ErrorAction = 'Stop'\n    }\n    $doAppInitAfterRestart = $null\n    try {\n        $doAppInitAfterRestart = (Get-WebConfigurationProperty @getDoAppInitParams).Value\n    } catch {\n        $doAppInitAfterRestart = \"Not available\"\n    }\n\n    $getInitPagesParams = @{\n        pspath      = 'MACHINE/WEBROOT/APPHOST'\n        filter      = 'system.webServer/applicationInitialization'\n        name        = '.'\n        location    = $site\n        ErrorAction = 'Stop'\n    }\n    $preloadPage = $null\n    try {\n        $initPages = Get-WebConfigurationProperty @getInitPagesParams\n        if ($initPages -and $initPages.Collection -and $initPages.Collection.Count -gt 0) {\n            $preloadPage = $initPages.Collection[0].initializationPage\n        } else {\n            $preloadPage = \"Not configured\"\n        }\n    } catch {\n        $preloadPage = \"Not available\"\n    }\n\n    [PSCustomObject]@{\n        AppPool = $appPool\n        StartMode = $startMode\n        IdleTimeout = $idleTimeout\n        Site = $site\n        PreloadEnabled = $preloadEnabled\n        DoAppInitAfterRestart = $doAppInitAfterRestart\n        PreloadPage = $preloadPage\n        IISApplicationInitFeature = $iisAppInitState\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365installedhotfix.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get installed hotfix (DEPRECATED)\n        \n    .DESCRIPTION\n        Get all relevant details for installed hotfixes on environments that are not on a \"One Version\" version. This cmdlet is deprecated since 2021-10-05 and will be removed by 2022-04-05.\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the AOS Service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the PackagesLocalDirectory\n        \n        Default path is the same as the AOS Service PackagesLocalDirectory\n        \n    .PARAMETER Model\n        Name of the model that you want to work against\n        \n        Accepts wildcards for searching. E.g. -Model \"*Retail*\"\n        \n        Default value is \"*\" which will search for all models\n        \n    .PARAMETER Name\n        Name of the hotfix that you are looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"7045*\"\n        \n        Default value is \"*\" which will search for all hotfixes\n        \n    .PARAMETER KB\n        KB number of the hotfix that you are looking for\n        \n        Accepts wildcards for searching. E.g. -KB \"4045*\"\n        \n        Default value is \"*\" which will search for all KB's\n        \n    .EXAMPLE\n        PS C:\\> Get-D365InstalledHotfix\n        \n        This will display all installed hotfixes found on this machine\n        \n    .EXAMPLE\n        PS C:\\> Get-D365InstalledHotfix -Model \"*retail*\"\n        \n        This will display all installed hotfixes found for all models that matches the search for \"*retail*\" found on this machine\n        \n    .EXAMPLE\n        PS C:\\> Get-D365InstalledHotfix -Model \"*retail*\" -KB \"*43*\"\n        \n        This will display all installed hotfixes found for all models that matches the search for \"*retail*\" and only with KB's that matches the search for \"*43*\" found on this machine\n        \n    .NOTES\n        Tags: Hotfix, Servicing, Model, Models, KB, Patch, Patching, PackagesLocalDirectory\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        This cmdlet is inspired by the work of \"Ievgen Miroshnikov\" (twitter: @IevgenMir)\n        \n        All credits goes to him for showing how to extract these information\n        \n        His blog can be found here:\n        https://ievgensaxblog.wordpress.com\n        \n        The specific blog post that we based this cmdlet on can be found here:\n        https://ievgensaxblog.wordpress.com/2017/11/17/d365foe-get-list-of-installed-metadata-hotfixes-using-metadata-api/\n        \n#>\nfunction Get-D365InstalledHotfix {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )]\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )]\n        [string] $PackageDirectory = $Script:PackageDirectory,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 3 )]\n        [string] $Model = \"*\",\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 4 )]\n        [string] $Name = \"*\",\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 5 )]\n        [string] $KB = \"*\"\n\n    )\n\n    begin {\n    }\n\n    process {\n        $files = @((Join-Path -Path $BinDir -ChildPath \"Microsoft.Dynamics.AX.Metadata.Storage.dll\"),\n            (Join-Path -Path $BinDir -ChildPath \"Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll\"))\n        \n        if(-not (Test-PathExists -Path $files -Type Leaf)) {\n            return\n        }\n\n        Add-Type -Path $files\n\n        Write-PSFMessage -Level Verbose -Message \"Testing if the cmdlet is running on a OneBox or not.\" -Target $Script:IsOnebox\n        if ($Script:IsOnebox) {\n            Write-PSFMessage -Level Verbose -Message \"Machine is onebox. Will continue with DiskProvider.\"\n\n            $diskProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n            $diskProviderConfiguration.AddMetadataPath($PackageDirectory)\n            $metadataProviderFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n            $metadataProvider = $metadataProviderFactory.CreateDiskProvider($diskProviderConfiguration)\n\n            Write-PSFMessage -Level Verbose -Message \"MetadataProvider initialized.\" -Target $metadataProvider\n        }\n        else {\n            Write-PSFMessage -Level Verbose -Message \"Machine is NOT onebox. Will continue with RuntimeProvider.\"\n\n            $runtimeProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.Runtime.RuntimeProviderConfiguration -ArgumentList $Script:PackageDirectory\n            $metadataProviderFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n            $metadataProvider = $metadataProviderFactory.CreateRuntimeProvider($runtimeProviderConfiguration)\n\n            Write-PSFMessage -Level Verbose -Message \"MetadataProvider initialized.\" -Target $metadataProvider\n        }\n\n        Write-PSFMessage -Level Verbose -Message \"Initializing the UpdateProvider from the MetadataProvider.\"\n        $updateProvider = $metadataProvider.Updates\n\n        Write-PSFMessage -Level Verbose -Message \"Looping through all modules from the MetadataProvider.\"\n        foreach ($obj in $metadataProvider.ModelManifest.ListModules()) {\n            Write-PSFMessage -Level Verbose -Message \"Filtering out all modules that doesn't match the model search.\" -Target $obj\n            if ($obj.Name -NotLike $Model) {continue}\n\n            Write-PSFMessage -Level Verbose -Message \"Looping through all hotfixes for the module from the UpdateProvider.\" -Target $obj\n            foreach ($objUpdate in $updateProvider.ListObjects($obj.Name)) {\n                Write-PSFMessage -Level Verbose -Message \"Reading all details for the hotfix through UpdateProvider.\" -Target $objUpdate\n                \n                $axUpdateObject = $updateProvider.Read($objUpdate)\n\n                Write-PSFMessage -Level Verbose -Message \"Filtering out all hotfixes that doesn't match the name search.\" -Target $axUpdateObject\n                if ($axUpdateObject.Name -NotLike $Name) {continue}\n\n                Write-PSFMessage -Level Verbose -Message \"Filtering out all hotfixes that doesn't match the KB search.\" -Target $axUpdateObject\n                if ($axUpdateObject.KBNumbers -NotLike $KB) {continue}\n\n                [PSCustomObject]@{\n                    Model   = $obj.Name\n                    Hotfix  = $axUpdateObject.Name\n                    Applied = $axUpdateObject.AppliedDateTime\n                    KBs     = $axUpdateObject.KBNumbers\n                }\n            }\n        }\n    }\n\n    end {\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365installedpackage.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get installed package from Dynamics 365 Finance & Operations environment\n        \n    .DESCRIPTION\n        Get installed package from the machine running the AOS service for Dynamics 365 Finance & Operations\n        \n    .PARAMETER Name\n        Name of the package that you are looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"Application*Adaptor\"\n        \n        Default value is \"*\" which will search for all packages\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed packages\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Get-D365InstalledPackage\n        \n        Shows the entire list of installed packages located in the default location on the machine\n        \n        A result set example:\n        ApplicationFoundationFormAdaptor\n        ApplicationPlatformFormAdaptor\n        ApplicationSuiteFormAdaptor\n        ApplicationWorkspacesFormAdaptor\n        \n    .EXAMPLE\n        PS C:\\> Get-D365InstalledPackage -Name \"Application*Adaptor\"\n        \n        Shows the list of installed packages where the name fits the search \"Application*Adaptor\"\n        \n        A result set example:\n        ApplicationFoundationFormAdaptor\n        ApplicationPlatformFormAdaptor\n        ApplicationSuiteFormAdaptor\n        ApplicationWorkspacesFormAdaptor\n        \n    .EXAMPLE\n        PS C:\\> Get-D365InstalledPackage -PackageDirectory \"J:\\AOSService\\PackagesLocalDirectory\"\n        \n        Shows the entire list of installed packages located in \"J:\\AOSService\\PackagesLocalDirectory\" on the machine\n        \n        A result set example:\n        ApplicationFoundationFormAdaptor\n        ApplicationPlatformFormAdaptor\n        ApplicationSuiteFormAdaptor\n        ApplicationWorkspacesFormAdaptor\n        \n    .NOTES\n        Tags: PackagesLocalDirectory, Servicing, Model, Models, Package, Packages\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages.\n#>\nfunction Get-D365InstalledPackage {\n    [CmdletBinding()]\n    param (\n        [string] $Name = \"*\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    Write-PSFMessage -Level Verbose -Message \"Package directory is: $PackageDirectory\" -Target $PackageDirectory\n    Write-PSFMessage -Level Verbose -Message \"Name is: $Name\" -Target $Name\n\n    $Packages = Get-ChildItem -Path $PackageDirectory -Directory -Exclude bin\n\n    foreach ($obj in $Packages) {\n        if ($obj.Name -NotLike $Name) { continue }\n        [PSCustomObject]@{\n            PackageName      = $obj.Name\n            PackageDirectory = $obj.FullName\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365installedservice.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get installed D365 services\n        \n    .DESCRIPTION\n        Get installed Dynamics 365 for Finance & Operations services that are installed on the machine\n        \n    .PARAMETER Path\n        Path to the folder that contains the \"InstallationRecords\" folder\n        \n    .EXAMPLE\n        PS C:\\> Get-D365InstalledService\n        \n        This will get all installed services on the machine.\n        \n    .NOTES\n        Tags: Services, Servicing, Topology\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-D365InstalledService {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )]\n        [string] $Path = $Script:InstallationRecordsDir\n    )\n    \n    begin {\n    }\n    \n    process {\n        $servicePath = Join-Path $Path \"ServiceModelInstallationRecords\"\n\n        Write-PSFMessage -Level Verbose -Message \"Service installation log path is: $servicePath\" -Target $servicePath\n        $ServiceFiles = Get-ChildItem -Path $servicePath -Filter \"*_current.xml\" -Recurse\n\n        foreach ($obj in $ServiceFiles) {\n            [PSCustomObject]@{\n                ServiceName = ($obj.Name.Split(\"_\")[0])\n                Version     = (Select-Xml -XPath \"/ServiceModelInstallationInfo/Version\" -Path $obj.fullname).Node.\"#Text\"\n            }\n        }\n    }\n    \n    end {\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365instancename.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Gets the instance name\n        \n    .DESCRIPTION\n        Get the instance name that is registered in the environment\n        \n    .EXAMPLE\n        PS C:\\> Get-D365InstanceName\n        \n        This will get the service name that the environment has configured\n        \n    .NOTES\n        Tags: Instance, Servicing\n        \n        Author: Rasmus Andersen (@ITRasmus)\n        \n        The cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations.\n        The call to the dll file gets HostedServiceName that is registered in the environment.\n        \n#>\nfunction Get-D365InstanceName {\n    [CmdletBinding()]\n    param ()\n\n    [PSCustomObject]@{\n        InstanceName = \"$($(Get-D365EnvironmentSettings).Infrastructure.HostedServiceName)\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365jsonservice.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get Json based service\n        \n    .DESCRIPTION\n        Get Json based services that are available from a Dynamics 365 Finance & Operations environment\n        \n    .PARAMETER Name\n        The name of the json service that you are looking for\n        \n        Default value is \"*\" to display all json services\n        \n    .PARAMETER Url\n        URL / URI for the D365FO environment you want to access\n        \n        If you are working against a D365FO instance, it will be the URL / URI for the instance itself\n        \n        If you are working against a D365 Talent / HR instance, this will have to be \"http://hr.talent.dynamics.com\"\n        \n    .PARAMETER Tenant\n        Azure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to access\n        \n    .PARAMETER ClientId\n        The ClientId obtained from the Azure Portal when you created a Registered Application\n        \n    .PARAMETER ClientSecret\n        The ClientSecret obtained from the Azure Portal when you created a Registered Application\n        \n    .PARAMETER RawOutput\n        Instructs the cmdlet to include the outer structure of the response received from the endpoint\n        \n        The output will still be a PSCustomObject\n        \n    .PARAMETER OutputAsJson\n        Instructs the cmdlet to convert the output to a Json string\n        \n    .EXAMPLE\n        PS C:\\> Get-D365JsonService -Url \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" -Tenant \"e674da86-7ee5-40a7-b777-1111111111111\" -ClientId \"dea8d7a9-1602-4429-b138-111111111111\" -ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\"\n        \n        This will get all available service groups for the D365FO instance.\n        It will contact the D365FO instance specified in the Url parameter: \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\".\n        It will authenticate againt the \"https://login.microsoftonline.com/e674da86-7ee5-40a7-b777-1111111111111/oauth2/token\" url with the specified Tenant parameter: \"e674da86-7ee5-40a7-b777-1111111111111\".\n        It will authenticate with the specified ClientId parameter: \"dea8d7a9-1602-4429-b138-111111111111\".\n        It will authenticate with the specified ClientSecret parameter: \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\".\n        \n    .EXAMPLE\n        PS C:\\> Get-D365JsonService -Name \"*TS*\" -Url \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" -Tenant \"e674da86-7ee5-40a7-b777-1111111111111\" -ClientId \"dea8d7a9-1602-4429-b138-111111111111\" -ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\"\n        \n        This will get all available service groups for the D365FO instance, which matches the \"*TS*\" as a name.\n        It will contact the D365FO instance specified in the Url parameter: \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\".\n        It will authenticate againt the \"https://login.microsoftonline.com/e674da86-7ee5-40a7-b777-1111111111111/oauth2/token\" url with the specified Tenant parameter: \"e674da86-7ee5-40a7-b777-1111111111111\".\n        It will authenticate with the specified ClientId parameter: \"dea8d7a9-1602-4429-b138-111111111111\".\n        It will authenticate with the specified ClientSecret parameter: \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\".\n        It will limit the output to only those matching the specified Name parameter: \"*TS*\"\n        \n    .EXAMPLE\n        PS C:\\> Get-D365JsonService -Url \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" -Tenant \"e674da86-7ee5-40a7-b777-1111111111111\" -ClientId \"dea8d7a9-1602-4429-b138-111111111111\" -ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\" -RawOutput\n        \n        This will get all available service groups for the D365FO instance with the outer most hierarchy.\n        It will contact the D365FO instance specified in the Url parameter: \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\".\n        It will authenticate againt the \"https://login.microsoftonline.com/e674da86-7ee5-40a7-b777-1111111111111/oauth2/token\" url with the specified Tenant parameter: \"e674da86-7ee5-40a7-b777-1111111111111\".\n        It will authenticate with the specified ClientId parameter: \"dea8d7a9-1602-4429-b138-111111111111\".\n        It will authenticate with the specified ClientSecret parameter: \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\".\n        \n    .EXAMPLE\n        PS C:\\> Get-D365JsonService -Url \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" -Tenant \"e674da86-7ee5-40a7-b777-1111111111111\" -ClientId \"dea8d7a9-1602-4429-b138-111111111111\" -ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\" -OutputAsJson\n        \n        This will get all available service groups for the D365FO instance and display the result as json.\n        It will contact the D365FO instance specified in the Url parameter: \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\".\n        It will authenticate againt the \"https://login.microsoftonline.com/e674da86-7ee5-40a7-b777-1111111111111/oauth2/token\" url with the specified Tenant parameter: \"e674da86-7ee5-40a7-b777-1111111111111\".\n        It will authenticate with the specified ClientId parameter: \"dea8d7a9-1602-4429-b138-111111111111\".\n        It will authenticate with the specified ClientSecret parameter: \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\".\n        \n    .NOTES\n        Tags: DMF, OData, RestApi, Data Management Framework\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        Idea taken from http://www.ksaelen.be/wordpresses/dynamicsaxblog/2016/01/dynamics-ax-7-tip-what-services-are-exposed/\n        \n#>\nfunction Get-D365JsonService {\n    [CmdletBinding()]\n    [OutputType([System.String])]\n    param (\n        [string] $Name = \"*\",\n\n        [Parameter(Mandatory = $true)]\n        [string] $Url,\n\n        [Parameter(Mandatory = $true)]\n        [string] $Tenant,\n\n        [Parameter(Mandatory = $true)]\n        [string] $ClientId,\n\n        [Parameter(Mandatory = $true)]\n        [string] $ClientSecret,\n\n        [switch] $RawOutput,\n\n        [switch] $OutputAsJson\n    )\n\n    $bearerParms = @{\n        Resource        = $Url\n        ClientId        = $ClientId\n        ClientSecret    = $ClientSecret\n        AuthProviderUri = \"https://login.microsoftonline.com/$Tenant/oauth2/token\"\n    }\n\n    $bearer = Invoke-ClientCredentialsGrant @bearerParms | Get-BearerToken\n\n    $headers = @{Authorization = $bearer }\n    $Url = $Url + \"/api/services\"\n\n    $res = Invoke-RestMethod -Method Get -Uri $Url -Headers $headers\n\n    if (-not $RawOutput) {\n        $res = $res.ServiceGroups | Where-Object { $_.Name -Like $Name -or $_.Name -eq $Name } | Sort-Object Name\n    }\n    else {\n        $res.ServiceGroups = @($res.ServiceGroups | Where-Object { $_.Name -Like $Name -or $_.Name -eq $Name }) | Sort-Object Name\n    }\n\n    if ($OutputAsJson) {\n        $res | ConvertTo-Json -Depth 10\n    }\n    else {\n        $res\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365label.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get label from the label file from Dynamics 365 Finance & Operations environment\n        \n    .DESCRIPTION\n        Get label from the label file from the running the Dynamics 365 Finance & Operations instance\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the AOS service PackagesLocalDirectory\\bin\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .PARAMETER LabelFileId\n        Name / Id of the label \"file\" that you want to work against\n        \n    .PARAMETER Language\n        Name / string representation of the language / culture you want to work against\n        \n        Default value is \"en-US\"\n        \n    .PARAMETER Name\n        Name of the label that you are looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"@PRO59*\"\n        \n        Default value is \"*\" which will search for all labels\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Label -LabelFileId PRO\n        \n        Shows the entire list of labels that are available from the PRO label file.\n        The language is defaulted to \"en-US\".\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Label -LabelFileId PRO -Language da\n        \n        Shows the entire list of labels that are available from the PRO label file.\n        Shows only all \"da\" (Danish) labels.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Label -LabelFileId PRO -Name \"@PRO59*\"\n        \n        Shows the labels available from the PRO label file where the name fits the search \"@PRO59*\"\n        \n        A result set example:\n        \n        Name                 Value                                                                            Language\n        ----                 -----                                                                            --------\n        @PRO59               Indicates if the type of the rebate value.                                       en-US\n        @PRO594              Pack consumption                                                                 en-US\n        @PRO595              Pack qty now being released to production in the BOM unit.                       en-US\n        @PRO596              Pack unit.                                                                       en-US\n        @PRO597              Pack proposal for release in the packing unit.                                   en-US\n        @PRO590              Constant pack qty                                                                en-US\n        @PRO593              Pack proposal release in BOM unit.                                               en-US\n        @PRO598              Pack quantity now being released for the production in the packing unit.         en-US\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Label -LabelFileId PRO -Name \"@PRO59*\" -Language da,en-us\n        \n        Shows the labels available from the PRO label file where the name fits the search \"@PRO59*\".\n        Shows for both \"da\" (Danish) and en-US (English)\n        \n    .NOTES\n        Tags: PackagesLocalDirectory, Servicing, Language, Labels, Label\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        This cmdlet is inspired by the work of \"Pedro Tornich\" (twitter: @ptornich)\n        \n        All credits goes to him for showing how to extract these information\n        \n        His github repository can be found here:\n        https://github.com/ptornich/LabelFileGenerator\n        \n#>\nfunction Get-D365Label {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )]\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 2 )]\n        [string] $LabelFileId,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 3 )]\n        [string[]] $Language = \"en-US\",\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 4 )]\n        [string] $Name = \"*\"\n    )\n\n    begin {\n    }\n\n    process {\n        $files = @((Join-Path -Path $BinDir -ChildPath \"Microsoft.Dynamics.AX.Xpp.AxShared.dll\"))\n        \n        if (-not (Test-PathExists -Path $files -Type Leaf)) {\n            return\n        }\n\n        Add-Type -Path $files\n\n        foreach ($item in $Language) {\n            $culture = New-Object System.Globalization.CultureInfo -ArgumentList $item\n\n            Write-PSFMessage -Level Verbose -Message \"Searching for label\" -Target $culture\n            \n            $labels = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetAllLabels($LabelFileId, $culture)\n            \n            foreach ($itemLabel in $labels) {\n                foreach ($key in $itemLabel.Keys) {\n                    if ($key -notlike $Name) { continue }\n\n                    [PSCustomObject]@{\n                        Name     = $Key\n                        Value    = $itemLabel[$key]\n                        Language = $item\n                        PSTypeName = 'D365FO.TOOLS.Label'\n                    }\n                }\n            }\n        }\n    }\n\n    end {\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365labelfile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get label file (ids) for packages / modules from Dynamics 365 Finance & Operations environment\n        \n    .DESCRIPTION\n        Get label file (ids) for packages / modules from the machine running the AOS service for Dynamics 365 Finance & Operations\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the AOS service PackagesLocalDirectory\\bin\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .PARAMETER Module\n        Name of the module that you want to work against\n        \n        Default value is \"*\" which will search for all modules\n        \n    .PARAMETER Name\n        Name of the label file (id) that you are looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"Acc*Receivable*\"\n        \n        Default value is \"*\" which will search for all label file (ids)\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LabelFile\n        \n        Shows the entire list of label file (ids) for all installed packages / modules located in the default location on the machine\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LabelFile -Name \"Acc*Receivable*\"\n        \n        Shows the list of label file (ids) for all installed packages / modules where the label file (ids) name fits the search \"Acc*Receivable*\"\n        \n        A result set example:\n        \n        LabelFileId                        Languages              Module\n        -----------                        ---------              ------\n        AccountsReceivable                 {ar-AE, ar, cs, da...} ApplicationSuite\n        AccountsReceivable_SalesTaxCodesSA {en-US}                ApplicationSuite\n        \n        \n    .EXAMPLE\n        PS C:\\> Get-D365LabelFile -PackageDirectory \"J:\\AOSService\\PackagesLocalDirectory\"\n        \n        Shows the list of label file (ids) for all installed packages / modules located in \"J:\\AOSService\\PackagesLocalDirectory\" on the machine\n        \n    .NOTES\n        Tags: PackagesLocalDirectory, Servicing, Language, Labels, Label\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        This cmdlet is inspired by the work of \"Pedro Tornich\" (twitter: @ptornich)\n        \n        All credits goes to him for showing how to extract these information\n        \n        His github repository can be found here:\n        https://github.com/ptornich/LabelFileGenerator\n        \n#>\nfunction Get-D365LabelFile {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )]\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )]\n        [string] $PackageDirectory = $Script:PackageDirectory,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 3 )]\n        [Alias(\"ModuleName\")]\n        [string] $Module = \"*\",\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 4 )]\n        [string] $Name = \"*\"\n    )\n\n    begin {\n    }\n\n    process {\n        $files = @((Join-Path -Path $BinDir -ChildPath \"Microsoft.Dynamics.AX.Metadata.Storage.dll\"),\n            (Join-Path -Path $BinDir -ChildPath \"Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll\"))\n        \n        if(-not (Test-PathExists -Path $files -Type Leaf)) {\n            return\n        }\n\n        Add-Type -Path $files\n\n        Write-PSFMessage -Level Verbose -Message \"Testing if the cmdlet is running on a OneBox or not.\" -Target $Script:IsOnebox\n        if ($Script:IsOnebox) {\n            Write-PSFMessage -Level Verbose -Message \"Machine is onebox. Will continue with DiskProvider.\"\n\n            $diskProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n            $diskProviderConfiguration.AddMetadataPath($PackageDirectory)\n            $metadataProviderFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n            $metadataProvider = $metadataProviderFactory.CreateDiskProvider($diskProviderConfiguration)\n\n            Write-PSFMessage -Level Verbose -Message \"MetadataProvider initialized.\" -Target $metadataProvider\n        }\n        else {\n            Write-PSFMessage -Level Verbose -Message \"Machine is NOT onebox. Will continue with RuntimeProvider.\"\n\n            $runtimeProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.Runtime.RuntimeProviderConfiguration -ArgumentList $Script:PackageDirectory\n            $metadataProviderFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n            $metadataProvider = $metadataProviderFactory.CreateRuntimeProvider($runtimeProviderConfiguration)\n\n            Write-PSFMessage -Level Verbose -Message \"MetadataProvider initialized.\" -Target $metadataProvider\n        }\n\n        Write-PSFMessage -Level Verbose -Message \"Initializing the LabelProvider from the MetadataProvider.\"\n        $labelProvider = $metadataProvider.LabelFiles\n\n        $res = New-Object 'System.Collections.Generic.Dictionary[string, System.Collections.ArrayList]'\n\n        Write-PSFMessage -Level Verbose -Message \"Looping through all modules from the MetadataProvider.\"\n        foreach ($obj in $metadataProvider.ModelManifest.ListModules()) {\n            Write-PSFMessage -Level Verbose -Message \"Filtering out all modules that doesn't match the model search.\" -Target $obj\n            if ($obj.Name -NotLike $Module) {continue}\n\n            Write-PSFMessage -Level Verbose -Message \"$($obj.Name)\"\n\n            $labelFiles = $labelProvider.ListObjects($obj.Name)\n\n            foreach ($objLabelFile in $labelFiles) {\n                Write-PSFMessage -Level Verbose -Message \"$($objLabelFile)\"\n\n                if($objLabelFile -like \"*.*\") {\n                    $chars = $objLabelFile.ToCharArray()\n                    $chars[$objLabelFile.LastIndexOf(\".\")] = \"_\"\n                    $objLabelFile = $chars -join \"\"\n                }\n\n                $labelId = $objLabelFile.Substring(0, $objLabelFile.LastIndexOf(\"_\"))\n                $langString = $objLabelFile.Substring($objLabelFile.LastIndexOf(\"_\") + 1)\n\n                if ($labelId -NotLike $Name) {continue}\n\n                if(-not ($res.ContainsKey($labelId))) {\n                    $null = $res.Add($labelId, (New-object -TypeName \"System.Collections.ArrayList\"))\n                }\n\n                $null = $res[$labelId].Add($langString)\n            }\n\n            foreach ($item in $res.Keys) {\n\n                [PSCustomObject]@{\n                    LabelFileId   = $item\n                    Languages  = $res[$item]\n                    Module = $obj.Name\n                }\n            }\n            \n        }\n    }\n\n    end {\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365language.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get installed languages from Dynamics 365 Finance & Operations environment\n        \n    .DESCRIPTION\n        Get installed languages from the running the Dynamics 365 Finance & Operations instance\n        \n    .PARAMETER BinDir\n        Path to the directory containing the BinDir and its assemblies\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .PARAMETER Name\n        Name of the language that you are looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"fr*\"\n        \n        Default value is \"*\" which will search for all languages\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Language\n        \n        Shows the entire list of installed languages that are available from the running instance\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Language -Name \"fr*\"\n        \n        Shows the list of installed languages where the name fits the search \"fr*\"\n        \n        A result set example:\n        fr      French\n        fr-BE   French (Belgium)\n        fr-CA   French (Canada)\n        fr-CH   French (Switzerland)\n        \n    .NOTES\n        Tags: PackagesLocalDirectory, Servicing, Language, Labels, Label\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        This cmdlet is inspired by the work of \"Pedro Tornich\" (twitter: @ptornich)\n        \n        All credits goes to him for showing how to extract these information\n        \n        His github repository can be found here:\n        https://github.com/ptornich/LabelFileGenerator\n        \n#>\nfunction Get-D365Language {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )]\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )]\n        [string] $Name = \"*\"\n    )\n\n    begin {\n    }\n\n    process {\n        $files = @((Join-Path -Path $BinDir -ChildPath \"Microsoft.Dynamics.AX.Xpp.AxShared.dll\"))\n        \n        if(-not (Test-PathExists -Path $files -Type Leaf)) {\n            return\n        }\n\n        Add-Type -Path $files\n\n        $languages = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetInstalledLanguages()\n\n        foreach ($obj in $languages) {\n            Write-PSFMessage -Level Verbose -Message \"Filtering out all modules that doesn't match the model search.\" -Target $obj\n            if ($obj -NotLike $Name) {continue}\n\n            $lang = New-Object System.Globalization.CultureInfo -ArgumentList $obj\n            [PSCustomObject]@{\n                Name        = $obj\n                LanguageName  = $lang.DisplayName\n            }\n        }\n    }\n\n    end {\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365lcsapiconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the LCS configuration details\n        \n    .DESCRIPTION\n        Get the LCS configuration details from the configuration store\n        \n        All settings retrieved from this cmdlets is to be considered the default parameter values across the different cmdlets\n        \n    .PARAMETER OutputAsHashtable\n        Instruct the cmdlet to return a hashtable object\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsApiConfig\n        \n        This will output the current LCS API configuration.\n        The object returned will be a PSCustomObject.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsApiConfig -OutputAsHashtable\n        \n        This will output the current LCS API configuration.\n        The object returned will be a Hashtable.\n        \n    .LINK\n        Get-D365LcsApiToken\n        \n    .LINK\n        Get-D365LcsAssetValidationStatus\n        \n    .LINK\n        Get-D365LcsDeploymentStatus\n        \n    .LINK\n        Invoke-D365LcsApiRefreshToken\n        \n    .LINK\n        Invoke-D365LcsDeployment\n        \n    .LINK\n        Invoke-D365LcsUpload\n        \n    .LINK\n        Set-D365LcsApiConfig\n        \n    .NOTES\n        Tags: Environment, Url, Config, Configuration, LCS, Upload, ClientId\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Get-D365LcsApiConfig {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [switch] $OutputAsHashtable\n    )\n\n    Invoke-TimeSignal -Start\n\n    $res = [Ordered]@{}\n\n    Write-PSFMessage -Level Verbose -Message \"Extracting all the LCS configuration and building the result object.\"\n\n    foreach ($config in Get-PSFConfig -FullName \"d365fo.tools.lcs.*\") {\n        $propertyName = $config.FullName.ToString().Replace(\"d365fo.tools.lcs.\", \"\")\n        $res.$propertyName = $config.Value\n    }\n\n    if($OutputAsHashtable) {\n        $res\n    } else {\n        [PSCustomObject]$res\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365lcsapitoken.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get a valid OAuth 2.0 access token for LCS\n        \n    .DESCRIPTION\n        Get a valid OAuth 2.0 access token for LCS, by providing an easy way to work against the Azure AD of your tenant\n        \n    .PARAMETER ClientId\n        The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER Username\n        The username of the account that you want to impersonate\n        \n        It can either be your personal account or a service account\n        \n    .PARAMETER Password\n        The password of the account that you want to impersonate\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsApiToken -ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" -Username \"serviceaccount@domain.com\" -Password \"TopSecretPassword\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will obtain a valid OAuth 2.0 access token from Azure Active Directory.\n        The ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" is used in the OAuth 2.0 Grant Flow to authenticate.\n        The Username \"serviceaccount@domain.com\" and Password \"TopSecretPassword\" is used in the OAuth 2.0 Grant Flow, to approved that the application should impersonate like \"serviceaccount@domain.com\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsApiToken -ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" -Username \"serviceaccount@domain.com\" -Password \"TopSecretPassword\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\" | Set-D365LcsApiConfig -ProjectId 123456789\n        \n        This will obtain a valid OAuth 2.0 access token from Azure Active Directory.\n        The ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" is used in the OAuth 2.0 Grant Flow to authenticate.\n        The Username \"serviceaccount@domain.com\" and Password \"TopSecretPassword\" is used in the OAuth 2.0 Grant Flow, to approved that the application should impersonate like \"serviceaccount@domain.com\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n        The output object received from Get-D365LcsApiToken is piped directly to Set-D365LcsApiConfig.\n        \n        Set-D365LcsApiConfig will save the ClientId, LcsApiUri, ProjectId, access_token(BearerToken), refresh_token(RefreshToken), expires_on(ActiveTokenExpiresOn) details for the module to use them across other LCS cmdlets.\n        \n        This should be your default approach in using and leveraging the module, so you don't have to supply the same parameters for every single cmdlet.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsApiToken -Username \"serviceaccount@domain.com\" -Password \"TopSecretPassword\"\n        \n        This will obtain a valid OAuth 2.0 access token from Azure Active Directory.\n        The Username \"serviceaccount@domain.com\" and Password \"TopSecretPassword\" is used in the OAuth 2.0 Grant Flow, to approved that the application should impersonate like \"serviceaccount@domain.com\".\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsApiToken -Username \"serviceaccount@domain.com\" -Password \"TopSecretPassword\" | Set-D365LcsApiConfig\n        \n        This will obtain a valid OAuth 2.0 access token from Azure Active Directory and save the needed details.\n        The Username \"serviceaccount@domain.com\" and Password \"TopSecretPassword\" is used in the OAuth 2.0 Grant Flow, to approved that the application should impersonate like \"serviceaccount@domain.com\".\n        The output object received from Get-D365LcsApiToken is piped directly to Set-D365LcsApiConfig.\n        Set-D365LcsApiConfig will save the access_token(BearerToken), refresh_token(RefreshToken) and expires_on(ActiveTokenExpiresOn).\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .LINK\n        Get-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsAssetValidationStatus\n        \n    .LINK\n        Get-D365LcsDeploymentStatus\n        \n    .LINK\n        Invoke-D365LcsApiRefreshToken\n        \n    .LINK\n        Invoke-D365LcsDeployment\n        \n    .LINK\n        Invoke-D365LcsUpload\n        \n    .LINK\n        Set-D365LcsApiConfig\n        \n    .NOTES\n        Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Get-D365LcsApiToken {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidUsingPlainTextForPassword\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidUsingUserNameAndPassWordParams\", \"\")]\n    [CmdletBinding()]\n    [OutputType()]\n    param(\n        [Parameter(Mandatory = $false)]\n        [string] $ClientId = $Script:LcsApiClientId,\n\n        [Parameter(Mandatory = $true)]\n        [string] $Username,\n\n        [Parameter(Mandatory = $true)]\n        [string] $Password,\n\n        [Parameter(Mandatory = $false)]\n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [switch] $EnableException\n    )\n\n    Invoke-TimeSignal -Start\n\n    $tokenParms = @{ }\n    $tokenParms.Resource = $LcsApiUri\n    $tokenParms.ClientId = $ClientId\n    $tokenParms.Username = $Username\n    $tokenParms.Password = $Password\n    $tokenParms.Scope = \"openid\"\n    $tokenParms.AuthProviderUri = $Script:AADOAuthEndpoint\n\n    Invoke-PasswordGrant @tokenParms\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365lcsassetfile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get file from the Asset library inside the LCS project\n        \n    .DESCRIPTION\n        Get the available files from the Asset Library in LCS project\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER FileType\n        Type of file you want to list from the LCS Asset Library\n        \n        Valid options:\n        \"Model\"\n        \"Process Data Package\"\n        \"Software Deployable Package\"\n        \"GER Configuration\"\n        \"Data Package\"\n        \"PowerBI Report Model\"\n        \"E-Commerce Package\"\n        \"NuGet Package\"\n        \"Retail Self-Service Package\"\n        \"Commerce Cloud Scale Unit Extension\"\n        \n        \n        Default value is \"Software Deployable Package\"\n        \n    .PARAMETER AssetName\n        Name of the asset that you are looking for\n        \n        Accepts wildcards for searching. E.g. -AssetName \"*ISV*\"\n        \n        Default value is \"*\" which will search for all assets via the Name property\n        \n    .PARAMETER AssetVersion\n        Version of the Asset file that you are looking for\n        \n        It does a simple compare against the response from LCS and only lists the ones that matches\n        \n        Accepts wildcards for searching. E.g. -AssetVersion \"*ISV*\"\n        \n        Default value is \"*\" which will search for all files\n        \n    .PARAMETER AssetFilename\n        Name of the file that you are looking for\n        \n        Accepts wildcards for searching. E.g. -AssetFilename \"*ISV*\"\n        \n        Default value is \"*\" which will search for all files via the FileName property\n        \n    .PARAMETER AssetDescription\n        Name of the file that you are looking for\n        \n        Accepts wildcards for searching. E.g. -AssetDescription \"*ISV*\"\n        \n        Default value is \"*\" which will search for all files via the FileDescription property\n        \n    .PARAMETER AssetId\n        Id of the file that you are looking for\n        \n        Accepts wildcards for searching. E.g. -AssetId \"*ISV*\"\n        \n        Default value is \"*\" which will search for all files via the AssetId property\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER Latest\n        Instruct the cmdlet to only fetch the latest file from the Asset Library from LCS\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsAssetFile -ProjectId 123456789 -FileType SoftwareDeployablePackage -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will list all Software Deployable Packages.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage\n        \n        This will list all Software Deployable Packages.\n        It will search for SoftwareDeployablePackage by using the FileType parameter.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetFilename \"*MAIN*\"\n        \n        This will list all Software Deployable Packages, that matches the \"*MAIN*\" search pattern in the AssetFilename.\n        It will search for SoftwareDeployablePackage by using the FileType parameter.\n        It will filter the output to match the AssetFilename \"*MAIN*\" search pattern.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetName \"*MAIN*\"\n        \n        This will list all Software Deployable Packages, that matches the \"*MAIN*\" search pattern in the AssetName.\n        It will search for SoftwareDeployablePackage by using the FileType parameter.\n        It will filter the output to match the AssetName \"*MAIN*\" search pattern.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetDescription \"*TEST*\"\n        \n        This will list all Software Deployable Packages, that matches the \"*TEST*\" search pattern in the AssetDescription.\n        It will search for SoftwareDeployablePackage by using the FileType parameter.\n        It will filter the output to match the AssetDescription \"*TEST*\" search pattern.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetId \"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\"\n        \n        This will list all Software Deployable Packages, that matches the \"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\" search pattern in the AssetId.\n        It will search for SoftwareDeployablePackage by using the FileType parameter.\n        It will filter the output to match the AssetId \"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\" search pattern.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -Latest | Invoke-D365AzCopyTransfer -DestinationUri C:\\Temp\\d365fo.tools -FileName \"Main.zip\" -ShowOriginalProgress\n        \n        This will download the latest Software Deployable Package from the Asset Library in LCS onto your on machine.\n        It will list Software Deployable Packages based on the FileType parameter.\n        It will list the latest (newest) Software Deployable Package.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -RetryTimeout \"00:01:00\"\n        \n        This will list all Software Deployable Packages, and allow for the cmdlet to retry for no more than 1 minute.\n        It will search for SoftwareDeployablePackage by using the FileType parameter.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .LINK\n        Get-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsApiToken\n        \n    .LINK\n        Invoke-D365LcsApiRefreshToken\n        \n    .LINK\n        Set-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsSharedAssetFile\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Get-D365LcsAssetFile {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [int] $ProjectId = $Script:LcsApiProjectId,\n\n        [LcsAssetFileType] $FileType = [LcsAssetFileType]::SoftwareDeployablePackage,\n\n        [string] $AssetName = \"*\",\n\n        [string] $AssetVersion = \"*\",\n\n        [string] $AssetFilename = \"*\",\n\n        [string] $AssetDescription = \"*\",\n\n        [string] $AssetId = \"*\",\n        \n        [Alias('Token')]\n        [string] $BearerToken = $Script:LcsApiBearerToken,\n\n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [Alias('GetLatest')]\n        [switch] $Latest,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    Invoke-TimeSignal -Start\n\n    if (-not ($BearerToken.StartsWith(\"Bearer \"))) {\n        $BearerToken = \"Bearer $BearerToken\"\n    }\n\n    $assets = Get-LcsAssetFileV2 -BearerToken $BearerToken -ProjectId $ProjectId -LcsApiUri $LcsApiUri -FileType $([int]$FileType) -RetryTimeout $RetryTimeout\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    if ($Latest) {\n        $assets | Sort-Object -Property \"ModifiedDate\" -Descending | Select-Object -First 1 | Select-PSFObject -TypeName \"D365FO.TOOLS.Lcs.Asset.File\" \"*\", \"Id as AssetId\"\n    }\n    else {\n        foreach ($obj in $assets) {\n            if ($obj.Name -NotLike $AssetName) { continue }\n            if ($obj.Version -NotLike $AssetVersion) { continue }\n            if ($obj.FileName -NotLike $AssetFilename) { continue }\n            if ($obj.FileDescription -NotLike $AssetDescription) { continue }\n            if ($obj.Id -NotLike $AssetId) { continue }\n\n            $obj | Select-PSFObject -TypeName \"D365FO.TOOLS.Lcs.Asset.File\" \"*\", \"Id as AssetId\"\n        }\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365lcsassetvalidationstatus.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the validation status from LCS\n        \n    .DESCRIPTION\n        Get the validation status for a given file in the Asset Library in LCS\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER AssetId\n        The unique id of the asset / file that you are trying to deploy from LCS\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER WaitForValidation\n        Instruct the cmdlet to wait for the validation process to complete\n        \n        The cmdlet will sleep for 60 seconds, before requesting the status of the validation process from LCS\n        \n    .PARAMETER SleepInSeconds\n        Time in seconds that you want the cmdlet to use as the sleep timer between each request against the LCS endpoint\n        \n        Default value is 60\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsAssetValidationStatus -ProjectId 123456789 -BearerToken \"JldjfafLJdfjlfsalfd...\" -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will check the validation status for the file in the Asset Library.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\n        The request will authenticate with the BearerToken \"Bearer JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsAssetValidationStatus -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\"\n        \n        This will check the validation status for the file in the Asset Library.\n        The file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsAssetValidationStatus -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -WaitForValidation\n        \n        This will check the validation status for the file in the Asset Library.\n        The file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\n        The cmdlet will every 60 seconds contact the LCS API endpoint and check if the status of the validation is either success or failure.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsUpload -FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\" | Get-D365LcsAssetValidationStatus -WaitForValidation\n        \n        This will start the upload of a file to the Asset Library and check the validation status for the file in the Asset Library.\n        The file that will be uploaded is based on the FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\".\n        The output object received from Invoke-D365LcsUpload is piped directly to Get-D365LcsAssetValidationStatus.\n        The cmdlet will every 60 seconds contact the LCS API endpoint and check if the status of the validation is either success or failure.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsAssetValidationStatus -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -RetryTimeout \"00:01:00\"\n        \n        This will check the validation status for the file in the Asset Library, and allow for the cmdlet to retry for no more than 1 minute.\n        The file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .LINK\n        Get-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsApiToken\n        \n    .LINK\n        Get-D365LcsDeploymentStatus\n        \n    .LINK\n        Invoke-D365LcsApiRefreshToken\n        \n    .LINK\n        Invoke-D365LcsDeployment\n        \n    .LINK\n        Invoke-D365LcsUpload\n        \n    .LINK\n        Set-D365LcsApiConfig\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Get-D365LcsAssetValidationStatus {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]\n        [string] $AssetId,\n        \n        [int] $ProjectId = $Script:LcsApiProjectId,\n        \n        [Alias('Token')]\n        [string] $BearerToken = $Script:LcsApiBearerToken,\n\n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [switch] $WaitForValidation,\n\n        [int] $SleepInSeconds = 60,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n\n    process {\n        Invoke-TimeSignal -Start\n\n        if (-not ($BearerToken.StartsWith(\"Bearer \"))) {\n            $BearerToken = \"Bearer $BearerToken\"\n        }\n\n        do {\n            Write-PSFMessage -Level Verbose -Message \"Sleeping before hitting the LCS API for Asset Validation Status\"\n            \n            Start-Sleep -Seconds $SleepInSeconds\n\n            $status = Get-LcsAssetValidationStatusV2 -BearerToken $BearerToken -ProjectId $ProjectId -AssetId $AssetId -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout\n        \n            if (Test-PSFFunctionInterrupt) { return }\n        }\n        while (($status.DisplayStatus -eq \"Process\") -and $WaitForValidation)\n\n        Invoke-TimeSignal -End\n\n        $status | Select-PSFObject \"ID as AssetId\", \"DisplayStatus as Status\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365lcsdatabasebackups.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get database backups from LCS project\n        \n    .DESCRIPTION\n        Get the available database backups from the Asset Library in LCS project\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER Latest\n        Instruct the cmdlet to only fetch the latest file from the Azure Storage Account\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsDatabaseBackups -ProjectId 123456789 -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will get all available database backups from the Asset Library inside LCS.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"Bearer JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsDatabaseBackups\n        \n        This will get all available database backups from the Asset Library inside LCS.\n        It will use default values for all parameters.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsDatabaseBackups -Latest\n        \n        This will get the latest available database backup from the Asset Library inside LCS.\n        It will use default values for all parameters.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsDatabaseBackups -Latest -RetryTimeout \"00:01:00\"\n        \n        This will get the latest available database backup from the Asset Library inside LCS, and allow for the cmdlet to retry for no more than 1 minute.\n        It will use default values for all parameters.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .LINK\n        Get-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsApiToken\n        \n    .LINK\n        Invoke-D365LcsApiRefreshToken\n        \n    .LINK\n        Set-D365LcsApiConfig\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Get-D365LcsDatabaseBackups {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [int] $ProjectId = $Script:LcsApiProjectId,\n        \n        [Alias('Token')]\n        [string] $BearerToken = $Script:LcsApiBearerToken,\n\n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [Alias('GetLatest')]\n        [switch] $Latest,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    Invoke-TimeSignal -Start\n\n    if (-not ($BearerToken.StartsWith(\"Bearer \"))) {\n        $BearerToken = \"Bearer $BearerToken\"\n    }\n\n    $backups = Get-LcsDatabaseBackupsV2 -BearerToken $BearerToken -ProjectId $ProjectId -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    if ($Latest) {\n        $backups.DatabaseAssets | Sort-Object -Property \"CreatedDateTime\" -Descending | Select-Object -First 1\n    }\n    else {\n        $backups.DatabaseAssets\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365lcsdatabaseoperationstatus.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the status of a database operation from LCS\n        \n    .DESCRIPTION\n        Get the current status of a database operation against an environment from a LCS project\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER OperationActivityId\n        The unique id of the operaction activity that identitfies the database operation\n        \n        It will be part of the output from the different Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets\n        \n    .PARAMETER EnvironmentId\n        The unique id of the environment that you want to work against\n        \n        The Id can be located inside the LCS portal\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER WaitForCompletion\n        Instruct the cmdlet to wait for the deployment process to complete\n        \n        The cmdlet will sleep for 300 seconds, before requesting the status of the deployment process from LCS\n        \n    .PARAMETER SleepInSeconds\n        Time in seconds that you want the cmdlet to use as the sleep timer between each request against the LCS endpoint\n        \n        Default value is 300\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsDatabaseOperationStatus -ProjectId 123456789 -OperationActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will check the database operation status of a specific OperationActivityId against an environment.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsDatabaseOperationStatus -OperationActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n        \n        This will check the database operation status of a specific OperationActivityId against an environment.\n        The OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsDatabaseOperationStatus -OperationActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -WaitForCompletion\n        \n        This will check the database operation status of a specific OperationActivityId against an environment.\n        The OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        The cmdlet will every 300 seconds contact the LCS API endpoint and check if the status of the database operation status is either success or failure.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsDatabaseOperationStatus -OperationActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -RetryTimeout \"00:01:00\"\n        \n        This will check the database operation status of a specific OperationActivityId against an environment, and allow for the cmdlet to retry for no more than 1 minute.\n        The OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .LINK\n        Get-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsApiToken\n        \n    .LINK\n        Get-D365LcsAssetValidationStatus\n        \n    .LINK\n        Invoke-D365LcsApiRefreshToken\n        \n    .LINK\n        Invoke-D365LcsDeployment\n        \n    .LINK\n        Invoke-D365LcsUpload\n        \n    .LINK\n        Set-D365LcsApiConfig\n        \n    .NOTES\n        Tags: Environment, Config, Configuration, LCS, Database backup, Api, Backup, Restore, Refresh\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Get-D365LcsDatabaseOperationStatus {\n    [CmdletBinding()]\n    [OutputType('PSCustomObject')]\n    param(\n        [int] $ProjectId = $Script:LcsApiProjectId,\n        \n        [Alias('Token')]\n        [string] $BearerToken = $Script:LcsApiBearerToken,\n\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]\n        [Alias('ActivityId')]\n        [string] $OperationActivityId,\n\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]\n        [Alias('SourceEnvironmentId')]\n        [string] $EnvironmentId,\n\n        [Parameter(Mandatory = $false)]\n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [switch] $WaitForCompletion,\n\n        [int] $SleepInSeconds = 300,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    process {\n        Invoke-TimeSignal -Start\n\n        if (-not ($BearerToken.StartsWith(\"Bearer \"))) {\n            $BearerToken = \"Bearer $BearerToken\"\n        }\n\n        do {\n            Write-PSFMessage -Level Verbose -Message \"Sleeping before hitting the LCS API for Deployment Status\"\n\n            Start-Sleep -Seconds $SleepInSeconds\n            $databaseOperationStatus = Get-LcsDatabaseOperationStatusV2 -BearerToken $BearerToken -ProjectId $ProjectId -OperationActivityId $OperationActivityId -EnvironmentId $EnvironmentId -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout\n\n            Write-PSFMessage -Level Verbose -Message \"Database Operation Status is: $($databaseOperationStatus.OperationStatus)\"\n        \n            if (Test-PSFFunctionInterrupt) { return }\n        }\n        while ((($databaseOperationStatus.OperationStatus -eq \"InProgress\") -or ($databaseOperationStatus.OperationStatus -eq \"NotStarted\") -or ($databaseOperationStatus.OperationStatus -eq \"RollbackInProgress\")) -and $WaitForCompletion)\n\n        Invoke-TimeSignal -End\n\n        $databaseOperationStatus | Select-PSFObject * -TypeName \"D365FO.TOOLS.LCS.Database.Operation.Status\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365lcsdeploymentstatus.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the Deployment status from LCS\n        \n    .DESCRIPTION\n        Get the Deployment status for activity against an environment from the Dynamics LCS Portal\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER ActivityId\n        The unique id of the action that you started from the Invoke-D365LcsDeployment cmdlet\n        \n    .PARAMETER EnvironmentId\n        The unique id of the environment that you want to work against\n        \n        The Id can be located inside the LCS portal\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER WaitForCompletion\n        Instruct the cmdlet to wait for the deployment process to complete\n        \n        The cmdlet will sleep for 300 seconds, before requesting the status of the deployment process from LCS\n        \n    .PARAMETER SleepInSeconds\n        Time in secounds that you want the cmdlet to use as the sleep timer between each request against the LCS endpoint\n        \n        Default value is 300\n        \n    .PARAMETER FailOnErrorMessage\n        Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n        \n        Used in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\n        This allows you to implement custom retry / error handling logic\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsDeploymentStatus -ProjectId 123456789 -ActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -BearerToken \"Bearer JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will check the deployment status of specific activity against an environment.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"Bearer JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsDeploymentStatus -ActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n        \n        This will check the deployment status of specific activity against an environment.\n        The activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsDeploymentStatus -ActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -WaitForCompletion\n        \n        This will check the deployment status of specific activity against an environment.\n        The activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        The cmdlet will every 300 seconds contact the LCS API endpoint and check if the status of the deployment is either success or failure.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsDeploymentStatus -ActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -RetryTimeout \"00:01:00\"\n        \n        This will check the deployment status of specific activity against an environment, and allow for the cmdlet to retry for no more than 1 minute.\n        The activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .LINK\n        Get-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsApiToken\n        \n    .LINK\n        Get-D365LcsAssetValidationStatus\n        \n    .LINK\n        Invoke-D365LcsApiRefreshToken\n        \n    .LINK\n        Invoke-D365LcsDeployment\n        \n    .LINK\n        Invoke-D365LcsUpload\n        \n    .LINK\n        Set-D365LcsApiConfig\n        \n    .NOTES\n        Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token, Deployment, Deploy\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Get-D365LcsDeploymentStatus {\n    [CmdletBinding()]\n    [OutputType('PSCustomObject')]\n    param(\n        [Parameter(Mandatory = $false)]\n        [int] $ProjectId = $Script:LcsApiProjectId,\n        \n        [Parameter(Mandatory = $false)]\n        [Alias('Token')]\n        [string] $BearerToken = $Script:LcsApiBearerToken,\n\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]\n        [Alias('ActionHistoryId')]\n        [string] $ActivityId,\n\n        [Parameter(Mandatory = $true)]\n        [string] $EnvironmentId,\n\n        [Parameter(Mandatory = $false)]\n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [switch] $WaitForCompletion,\n\n        [int] $SleepInSeconds = 300,\n\n        [switch] $FailOnErrorMessage,\n        \n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    process {\n        Invoke-TimeSignal -Start\n\n        if (-not ($BearerToken.StartsWith(\"Bearer \"))) {\n            $BearerToken = \"Bearer $BearerToken\"\n        }\n\n        do {\n            Write-PSFMessage -Level Verbose -Message \"Sleeping before hitting the LCS API for Deployment Status\"\n\n            Start-Sleep -Seconds $SleepInSeconds\n            $deploymentStatus = Get-LcsDeploymentStatusV2 -BearerToken $BearerToken -ProjectId $ProjectId -ActivityId $ActivityId -EnvironmentId $EnvironmentId -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout\n      \n            if (Test-PSFFunctionInterrupt) { return }\n\n            if ($FailOnErrorMessage -and $deploymentStatus.ErrorMessage) {\n                $messageString = \"The request against LCS succeeded, but the response was an error message for the operation: <c='em'>$($deploymentStatus.ErrorMessage)</c>.\"\n                $errorMessagePayload = \"`r`n$($deploymentStatus | ConvertTo-Json)\"\n                Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus\n                Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus\n            }\n        }\n        while ((($deploymentStatus.OperationStatus -eq \"InProgress\") -or ($deploymentStatus.OperationStatus -eq \"NotStarted\") -or ($deploymentStatus.OperationStatus -eq \"PreparingEnvironment\")) -and $WaitForCompletion)\n    \n        Invoke-TimeSignal -End\n\n        $deploymentStatus | Select-PSFObject * -TypeName \"D365FO.TOOLS.LCS.Deployment.Operation.Status\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365lcsenvironmenthistory.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get history for a given environment within a LCS project\n        \n    .DESCRIPTION\n        Get history details for a given environment from within a LCS project\n        \n        There can be multiple pages of data, which requires you to use the TraverseAllPages parameter, if you want all data to be shown\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n        \n    .PARAMETER EnvironmentId\n        Id of the environment that you want to be working against\n        \n    .PARAMETER TraverseAllPages\n        Instruct the cmdlet to fetch all pages, until there isn't more data available\n        \n        This can be a slow operation, as it has to call the LCS API multiple times, fetching a single page per call\n        \n    .PARAMETER FirstPages\n        Instruct the cmdlet how many pages that you want it to retrieve from the LCS API\n        \n        Can only be used in combination with -TraverseAllPages\n        \n        The default value is: 99 pages, which should be more than enough\n        \n        Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER FailOnErrorMessage\n        Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n        \n        Used in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\n        This allows you to implement custom retry / error handling logic\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsEnvironmentHistory -ProjectId \"123456789\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n        \n        This will list the first page of Environment History Data from the LCS API.\n        The LCS project is identified by the ProjectId \"123456789\", which can be obtained in the LCS portal.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        \n        A result set example:\n        \n        Name             : Service Update - 10.0.19\n        Type             : SFBinaryHotfix\n        TypeDisplay      : Binary hotfix\n        StartDateTimeUTC : 2021-07-11T00:01:57.423\n        EndDateTimeUTC   : 2021-07-11T05:01:12.97\n        Status           : Completed\n        ActivityId       : e3509860-61d4-4003-9b45-6ea7d89aea30\n        EnvironmentId    : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\n        ProjectId        : 123456789\n        \n        Name             : Refresh database\n        Type             : SFSourceDbToSandbox\n        TypeDisplay      : Refresh database\n        StartDateTimeUTC : 2021-06-06T15:17:48.87\n        EndDateTimeUTC   : 2021-06-06T16:33:40.367\n        Status           : Completed\n        ActivityId       : e3509860-61d4-4003-9b45-6ea7d89aea31\n        EnvironmentId    : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\n        ProjectId        : 123456789\n        \n        Name             : Export database\n        Type             : SFExportSandboxDb\n        TypeDisplay      : Export database\n        StartDateTimeUTC : 2021-04-27T22:08:01.103\n        EndDateTimeUTC   : 2021-04-28T23:30:06.623\n        Status           : RollbackCompleted\n        ActivityId       : e3509860-61d4-4003-9b45-6ea7d89aea32\n        EnvironmentId    : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\n        ProjectId        : 123456789\n        \n        Name             : Main_2021.1.1.1\n        Type             : SFApplicationHotfix\n        TypeDisplay      : Application deployable package\n        StartDateTimeUTC : 2021-03-04T21:44:20.793\n        EndDateTimeUTC   : 2021-03-04T22:48:17.303\n        Status           : Completed\n        ActivityId       : e3509860-61d4-4003-9b45-6ea7d89aea33\n        EnvironmentId    : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\n        ProjectId        : 123456789\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsEnvironmentHistory -ProjectId \"123456789\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -TraverseAllPages\n        \n        This will list the all the pages of Environment History Data from the LCS API.\n        The LCS project is identified by the ProjectId \"123456789\", which can be obtained in the LCS portal.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        The cmdlet will TraverseAllPages from the LCS API.\n        It will use the default value for the maximum number of pages to return, 99 pages.\n        \n        TraverseAllPages will increase the request time for completion, based on how many entries there is in the history.\n        Please be patient and let the system work for you.\n        \n        Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsEnvironmentHistory -ProjectId \"123456789\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -TraverseAllPages -FirstPages 2\n        \n        This will list the all the pages of Environment History Data from the LCS API.\n        The LCS project is identified by the ProjectId \"123456789\", which can be obtained in the LCS portal.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        The cmdlet will TraverseAllPages from the LCS API.\n        The cmdlet will be fetching the FirstPages 2, to limit the output from the cmdlet to only the newest 2 pages.\n        \n        TraverseAllPages will increase the request time for completion, based on how many entries there is in the history.\n        Please be patient and let the system work for you.\n        \n        Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Get-D365LcsEnvironmentHistory {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    [OutputType('PSCustomObject')]\n    param(\n        [int] $ProjectId = $Script:LcsApiProjectId,\n        \n        [Alias('Token')]\n        [string] $BearerToken = $Script:LcsApiBearerToken,\n\n        [Parameter(Mandatory = $true)]\n        [string] $EnvironmentId,\n\n        [Parameter(ParameterSetName = 'Pagination')]\n        [switch] $TraverseAllPages,\n\n        [Parameter(ParameterSetName = 'Pagination')]\n        [int] $FirstPages = 99,\n\n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [switch] $FailOnErrorMessage,\n        \n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    process {\n        Invoke-TimeSignal -Start\n\n        if (-not ($BearerToken.StartsWith(\"Bearer \"))) {\n            $BearerToken = \"Bearer $BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.ProjectId = $ProjectId\n        $parms.BearerToken = $BearerToken\n        $parms.EnvironmentId = $EnvironmentId\n        $parms.LcsApiUri = $LcsApiUri\n        $parms.RetryTimeout = $RetryTimeout\n        $parms.EnableException = $EnableException\n\n        [System.Collections.Generic.List[System.Object]] $resArray = @()\n        $page = 1\n\n        do {\n            $history = Get-LcsEnvironmentHistory @parms\n\n            $resArray.AddRange($history.Data)\n\n            if ($history.ResultHasMorePages -eq $true) {\n                $page += 1\n                $parms.Page = $page\n            }\n\n            if (Test-PSFFunctionInterrupt) { return }\n\n            if ($FailOnErrorMessage -and $deploymentStatus.ErrorMessage) {\n                $messageString = \"The request against LCS succeeded, but the response was an error message for the operation: <c='em'>$($deploymentStatus.ErrorMessage)</c>.\"\n                $errorMessagePayload = \"`r`n$($deploymentStatus | ConvertTo-Json)\"\n                Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus\n                Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus\n            }\n        }\n        while (($history.ResultHasMorePages -eq $true) -and $TraverseAllPages -and $page -le $FirstPages)\n    \n        $res = $null\n\n        if ($resArray.Count -gt 0) {\n            $res = $resArray.ToArray()\n        }\n        \n        Invoke-TimeSignal -End\n\n        $res | Select-PSFObject * -TypeName \"D365FO.TOOLS.LCS.Environment.History\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365lcsenvironmentmetadata.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get LCS environment meta data from within a project\n        \n    .DESCRIPTION\n        Get all meta data details for environments from within a LCS project\n        \n        It supports listing all environments, but also supports single / specific environments by searching based on EnvironmentId or EnvironmentName\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER EnvironmentId\n        Id of the environment that you want to be working against\n        \n    .PARAMETER EnvironmentName\n        Name of the environment that you want to be working against\n        \n    .PARAMETER TraverseAllPages\n        Instruct the cmdlet to fetch all pages, until there isn't more data available\n        \n        This can be a slow operation, as it has to call the LCS API multiple times, fetching a single page per call\n        \n    .PARAMETER FirstPages\n        Instruct the cmdlet how many pages that you want it to retrieve from the LCS API\n        \n        Can only be used in combination with -TraverseAllPages\n        \n        The default value is: 99 pages, which should be more than enough\n        \n        Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER FailOnErrorMessage\n        Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n        \n        Used in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\n        This allows you to implement custom retry / error handling logic\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsEnvironmentMetadata -ProjectId \"123456789\"\n        \n        This will show metadata for every available environment from the LCS project.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        \n        The request time for completion is directly impacted by the number of environments within the LCS project.\n        Please be patient and let the system work for you.\n        \n        You might experience that not all environments are listed with this request, that would indicate that the LCS project has many environments. Please use the -TraverseAllPages parameter to ensure that all environments are outputted.\n        \n        A result set example (Tier1):\n        \n        EnvironmentId                  : c6566087-23bd-4561-8247-4d7f4efd3172\n        EnvironmentName                : DevBox-01\n        ProjectId                      : 123456789\n        EnvironmentInfrastructure      : CustomerManaged\n        EnvironmentType                : DevTestDev\n        EnvironmentGroup               : Primary\n        EnvironmentProduct             : Finance and Operations\n        EnvironmentEndpointBaseUrl     : https://devbox-4d7f4efd3172devaos.cloudax.dynamics.com/\n        DeploymentState                : Stopped\n        TopologyDisplayName            : Finance and Operations - Develop (10.0.18 with Platform update 42)\n        CurrentApplicationBuildVersion : 10.0.793.41\n        CurrentApplicationReleaseName  : 10.0.18\n        CurrentPlatformReleaseName     : Update42\n        CurrentPlatformVersion         : 7.0.5968.16999\n        DeployedOnUTC                  : 7/5/2021 11:19 AM\n        CloudStorageLocation           : West Europe\n        DisasterRecoveryLocation       : North Europe\n        DeploymentStatusDisplay        : Stopped\n        CanStart                       : True\n        CanStop                        : False\n        \n        A result set example (Tier2+):\n        \n        EnvironmentId                  : e7c53b85-8b6a-4ab9-8985-1e1ea89a0f0a\n        EnvironmentName                : Contoso-SIT\n        ProjectId                      : 123456789\n        EnvironmentInfrastructure      : SelfService\n        EnvironmentType                : Sandbox\n        EnvironmentGroup               : Primary\n        EnvironmentProduct             : Finance and Operations\n        EnvironmentEndpointBaseUrl     : https://Contoso-SIT.sandbox.operations.dynamics.com/\n        DeploymentState                : Finished\n        TopologyDisplayName            : AXHA\n        CurrentApplicationBuildVersion : 10.0.761.10019\n        CurrentApplicationReleaseName  : 10.0.17\n        CurrentPlatformReleaseName     : PU41\n        CurrentPlatformVersion         : 7.0.5934.35741\n        DeployedOnUTC                  : 4/1/2020 9:35 PM\n        CloudStorageLocation           : West Europe\n        DisasterRecoveryLocation       :\n        DeploymentStatusDisplay        : Deployed\n        CanStart                       : False\n        CanStop                        : False\n        \n        A result set example (PROD):\n        \n        EnvironmentId                  : a8aab4f4-d4f3-41f0-af80-54cea83b50d2\n        EnvironmentName                : Contoso-PROD\n        ProjectId                      : 123456789\n        EnvironmentInfrastructure      : SelfService\n        EnvironmentType                : Production\n        EnvironmentGroup               : Primary\n        EnvironmentProduct             : Finance and Operations\n        EnvironmentEndpointBaseUrl     : https://Contoso-PROD.operations.dynamics.com/\n        DeploymentState                : Finished\n        TopologyDisplayName            : AXHA\n        CurrentApplicationBuildVersion : 10.0.886.48\n        CurrentApplicationReleaseName  : 10.0.20\n        CurrentPlatformReleaseName     : PU44\n        CurrentPlatformVersion         : 7.0.6060.45\n        DeployedOnUTC                  : 4/9/2020 12:11 PM\n        CloudStorageLocation           : West Europe\n        DisasterRecoveryLocation       :\n        DeploymentStatusDisplay        : Deployed\n        CanStart                       : False\n        CanStop                        : False\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsEnvironmentMetadata -ProjectId \"123456789\" -TraverseAllPages\n        \n        This will show metadata for every available environment from the LCS project, across multiple pages.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        It will use the default value for the maximum number of pages to return, 99 pages.\n        \n        TraverseAllPages will increase the request time for completion, based on how many entries there is in the history.\n        Please be patient and let the system work for you.\n        \n        Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsEnvironmentMetadata -ProjectId \"123456789\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n        \n        This will show metadata for every available environment from the LCS project.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsEnvironmentMetadata -ProjectId \"123456789\" -EnvironmentName \"Contoso-SIT\"\n        \n        This will show metadata for every available environment from the LCS project.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The environment is identified by the EnvironmentName \"Contoso-SIT\", which can be obtained in the LCS portal.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsEnvironmentMetadata -ProjectId \"123456789\" -TraverseAllPages -FirstPages 2\n        \n        This will show metadata for every available environment from the LCS project, across multiple pages.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        It will use the default value for the maximum number of pages to return, 99 pages.\n        The cmdlet will be fetching the FirstPages 2, to limit the output from the cmdlet to only the newest 2 pages.\n        \n        TraverseAllPages will increase the request time for completion, based on how many entries there is in the history.\n        Please be patient and let the system work for you.\n        \n        Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Get-D365LcsEnvironmentMetadata {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    [OutputType('PSCustomObject')]\n    param(\n        [int] $ProjectId = $Script:LcsApiProjectId,\n        \n        [Alias('Token')]\n        [string] $BearerToken = $Script:LcsApiBearerToken,\n\n        [Parameter(ParameterSetName = 'SearchByEnvironmentId')]\n        [string] $EnvironmentId,\n\n        [Parameter(ParameterSetName = 'SearchByEnvironmentName')]\n        [string] $EnvironmentName,\n      \n        [Parameter(ParameterSetName = 'Pagination')]\n        [switch] $TraverseAllPages,\n\n        [Parameter(ParameterSetName = 'Pagination')]\n        [int] $FirstPages = 99,\n\n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [switch] $FailOnErrorMessage,\n        \n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    process {\n        Invoke-TimeSignal -Start\n\n        if (-not ($BearerToken.StartsWith(\"Bearer \"))) {\n            $BearerToken = \"Bearer $BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.ProjectId = $ProjectId\n        $parms.BearerToken = $BearerToken\n        $parms.LcsApiUri = $LcsApiUri\n        $parms.RetryTimeout = $RetryTimeout\n        $parms.EnableException = $EnableException\n        \n        if ($PSCmdlet.ParameterSetName -eq \"SearchByEnvironmentId\") {\n            $parms.EnvironmentId = $EnvironmentId\n        }\n        elseif ($PSCmdlet.ParameterSetName -eq \"SearchByEnvironmentName\") {\n            $parms.EnvironmentName = $EnvironmentName\n        }\n\n        [System.Collections.Generic.List[System.Object]] $resArray = @()\n        $page = 1\n\n        do {\n            $metadata = Get-LcsEnvironmentMetadata @parms\n\n            $resArray.AddRange($metadata.Data)\n\n            if ($metadata.ResultHasMorePages -eq $true) {\n                $page += 1\n                $parms.Page = $page\n            }\n\n            if (Test-PSFFunctionInterrupt) { return }\n\n            if ($FailOnErrorMessage -and $deploymentStatus.ErrorMessage) {\n                $messageString = \"The request against LCS succeeded, but the response was an error message for the operation: <c='em'>$($deploymentStatus.ErrorMessage)</c>.\"\n                $errorMessagePayload = \"`r`n$($deploymentStatus | ConvertTo-Json)\"\n                Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus\n                Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus\n            }\n        }\n        while (($metadata.ResultHasMorePages -eq $true) -and $TraverseAllPages -and $page -le $FirstPages)\n    \n        $res = $null\n\n        if ($resArray.Count -gt 0) {\n            $res = $resArray.ToArray()\n        }\n        \n        Invoke-TimeSignal -End\n\n        $res | Select-PSFObject * -TypeName \"D365FO.TOOLS.LCS.Environment.Metadata\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365lcsenvironmentrsatcertificate.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get LCS environment rsat certificate from within a project\n        \n    .DESCRIPTION\n        Download and persist the active rsat certificate from environments from within a LCS project\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER EnvironmentId\n        Id of the environment that you want to be working against\n        \n    .PARAMETER OutputPath\n        Path to where you want the certificate files to be saved\n        \n        The default value is: \"c:\\temp\\d365fo.tools\\RsatCert\\\"\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER FailOnErrorMessage\n        Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n        \n        Used in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\n        This allows you to implement custom retry / error handling logic\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsEnvironmentRsatCertificate -ProjectId \"123456789\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n        \n        This will download the active rsat certificate file for the environment from the LCS project.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        \n        A result set example:\n        \n        Path     : c:\\temp\\d365fo.tools\\RsatCert\\RSATCertificate_ABC-UAT_20240101-012030\n        CerFile  : C:\\temp\\d365fo.tools\\RsatCert\\RSATCertificate_ABC-UAT_20240101-012030\\RSATCertificate_ABC-UAT_20240101-012030.cer\n        PfxFile  : C:\\temp\\d365fo.tools\\RsatCert\\RSATCertificate_ABC-UAT_20240101-012030\\RSATCertificate_ABC-UAT_20240101-012030.pfx\n        FileName : RSATCertificate_ABC-UAT_20240101-012030.zip\n        Password : 9zbPiLMTk676mkq5FvqQ\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsEnvironmentRsatCertificate -ProjectId \"123456789\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" | Import-D365RsatSelfServiceCertificates\n        \n        This will download the active rsat certificate file for the environment from the LCS project.\n        The resulting files are then imported into the certificate store on the local machine.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Get-D365LcsEnvironmentRsatCertificate {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    [OutputType('PSCustomObject')]\n    param(\n        [int] $ProjectId = $Script:LcsApiProjectId,\n        \n        [Alias('Token')]\n        [string] $BearerToken = $Script:LcsApiBearerToken,\n\n        [Parameter(Mandatory = $true)]\n        [string] $EnvironmentId,\n        \n        [string] $OutputPath = $(Join-Path $Script:DefaultTempPath \"RsatCert\"),\n\n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [switch] $FailOnErrorMessage,\n        \n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    process {\n        Invoke-TimeSignal -Start\n\n        if (-not (Test-PathExists -Path $OutputPath -Type Container -Create)) { return }\n\n        if (-not ($BearerToken.StartsWith(\"Bearer \"))) {\n            $BearerToken = \"Bearer $BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.ProjectId = $ProjectId\n        $parms.BearerToken = $BearerToken\n        $parms.LcsApiUri = $LcsApiUri\n        $parms.RetryTimeout = $RetryTimeout\n        $parms.EnableException = $EnableException\n        $parms.EnvironmentId = $EnvironmentId\n\n        $resCertDetails = Get-LcsEnvironmentRsatCertificate @parms\n           \n        if (Test-PSFFunctionInterrupt) { return }\n\n        if ($FailOnErrorMessage -and $deploymentStatus.ErrorMessage) {\n            $messageString = \"The request against LCS succeeded, but the response was an error message for the operation: <c='em'>$($deploymentStatus.ErrorMessage)</c>.\"\n            $errorMessagePayload = \"`r`n$($deploymentStatus | ConvertTo-Json)\"\n            Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus\n            Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus\n        }\n\n        $outFile = Join-Path -Path $OutputPath -ChildPath $resCertDetails.Data.Filename\n        Set-Content -Path $outFile -Value $([System.Convert]::FromBase64String($resCertDetails.Data.CertificateZipEncoded)) -Encoding Byte\n        \n        $outExtract = Join-Path -Path $OutputPath -ChildPath $([System.IO.Path]::GetFileNameWithoutExtension($outFile))\n        Expand-Archive -Path $outFile -DestinationPath $outExtract -Force\n\n        Invoke-TimeSignal -End\n\n        [PSCustomObject][ordered]@{\n            Path     = $outExtract\n            CerFile  = Get-Item -Path \"$outExtract\\*.cer\" | Select-Object -First 1 -ExpandProperty FullName\n            PfxFile  = Get-Item -Path \"$outExtract\\*.pfx\" | Select-Object -First 1 -ExpandProperty FullName\n            FileName = $resCertDetails.Data.Filename\n            Password = [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($resCertDetails.Data.CertificateSecretEncoded))\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365lcssharedassetfile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get information for assets from the shared asset library of LCS\n        \n    .DESCRIPTION\n        Get the information for the file assets from the shared asset library of LCS matching the search criteria\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n        Although the assets are stored in the shared asset library, their information is retrieved in context of a project to get the full information.\n        \n    .PARAMETER FileType\n        Type of file you want to list from the LCS Asset Library\n        \n        Valid options:\n        \"Model\"\n        \"Process Data Package\"\n        \"Software Deployable Package\"\n        \"GER Configuration\"\n        \"Data Package\"\n        \"PowerBI Report Model\"\n        \"E-Commerce Package\"\n        \"NuGet Package\"\n        \"Retail Self-Service Package\"\n        \"Commerce Cloud Scale Unit Extension\"\n        \n        Default value is \"Software Deployable Package\"\n        \n    .PARAMETER AssetName\n        Name of the asset that you are looking for\n        \n        Accepts wildcards for searching. E.g. -AssetName \"*ISV*\"\n        \n        Default value is \"*\" which will search for all assets via the Name property\n        \n    .PARAMETER AssetVersion\n        Version of the Asset file that you are looking for\n        \n        It does a simple compare against the response from LCS and only lists the ones that matches\n        \n        Accepts wildcards for searching. E.g. -AssetVersion \"*ISV*\"\n        \n        Default value is \"*\" which will search for all files\n        \n    .PARAMETER AssetFilename\n        Name of the file that you are looking for\n        \n        Accepts wildcards for searching. E.g. -AssetFilename \"*ISV*\"\n        \n        Default value is \"*\" which will search for all files via the FileName property\n        \n    .PARAMETER AssetDescription\n        Name of the file that you are looking for\n        \n        Accepts wildcards for searching. E.g. -AssetDescription \"*ISV*\"\n        \n        Default value is \"*\" which will search for all files via the FileDescription property\n        \n    .PARAMETER AssetId\n        Id of the file that you are looking for\n        \n        Accepts wildcards for searching. E.g. -AssetId \"*ISV*\"\n        \n        Default value is \"*\" which will search for all files via the AssetId property\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER Latest\n        Instruct the cmdlet to only fetch the latest file from the Asset Library from LCS\n        \n    .PARAMETER SkipSasGeneration\n        Instruct the cmdlet to only fetch the meta data from the asset file (entry)\n        \n        This is to speed up the listing of entries, in some of the larger areas in the Shared Asset Library\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        Usually this parameter is not used directly, but via the Enable-D365Exception cmdlet\n        See https://github.com/d365collaborative/d365fo.tools/wiki/Exception-handling#what-does-the--enableexception-parameter-do for further information\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsSharedAssetFile -ProjectId 123456789 -FileType SoftwareDeployablePackage -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will list all Software Deployable Packages in the shared asset library.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage\n        \n        This will list all Software Deployable Packages in the shared asset library.\n        It will search for SoftwareDeployablePackage by using the FileType parameter.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetFilename \"*MAIN*\"\n        \n        This will list all Software Deployable Packages in the shared asset library that match the \"*MAIN*\" search pattern in the file name of the asset.\n        It will search for SoftwareDeployablePackage by using the FileType parameter.\n        It will filter the output to match the AssetFilename \"*MAIN*\" search pattern.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetName \"*MAIN*\"\n        \n        This will list all Software Deployable Packages in the shared asset library that match the \"*MAIN*\" search pattern in the name of the asset.\n        It will search for SoftwareDeployablePackage by using the FileType parameter.\n        It will filter the output to match the AssetName \"*MAIN*\" search pattern.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetDescription \"*TEST*\"\n        \n        This will list all Software Deployable Packages in the shared asset library that match the \"*TEST*\" search pattern in the asset description.\n        It will search for SoftwareDeployablePackage by using the FileType parameter.\n        It will filter the output to match the AssetDescription \"*TEST*\" search pattern.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetId \"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\"\n        \n        This will list all Software Deployable Packages in the shared asset library that match the \"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\" search pattern in the asset id.\n        It will search for SoftwareDeployablePackage by using the FileType parameter.\n        It will filter the output to match the AssetId \"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\" search pattern.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> $asset = Get-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage -Latest\n        PS C:\\> Invoke-D365AzCopyTransfer -SourceUri $asset.FileLocation -DestinationUri C:\\Temp\\d365fo.tools\\$($asset.Filename) -ShowOriginalProgress\n        \n        This will download the latest Software Deployable Package from the shared asset library in LCS onto your local machine.\n        It will list Software Deployable Packages based on the FileType parameter.\n        It will list the latest (newest) Software Deployable Package.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage -RetryTimeout \"00:01:00\"\n        \n        This will list all Software Deployable Packages in the shared asset library and allow for the cmdlet to retry for no more than 1 minute.\n        It will search for SoftwareDeployablePackage by using the FileType parameter.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage -SkipSasGeneration\n        \n        This will list all Software Deployable Packages in the shared asset library, but skip the SAS / Download generation\n        It will search for SoftwareDeployablePackage by using the FileType parameter.\n        \n        This will increase the speed getting the list of assets - but you will not get a downloadable link.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .LINK\n        Get-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsApiToken\n        \n    .LINK\n        Invoke-D365LcsApiRefreshToken\n        \n    .LINK\n        Set-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsAssetFile\n        \n    .NOTES\n        Author: Florian Hopfner (@FH-Inway)\n        \n#>\n\nfunction Get-D365LcsSharedAssetFile {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [int] $ProjectId = $Script:LcsApiProjectId,\n\n        [LcsAssetFileType] $FileType = [LcsAssetFileType]::SoftwareDeployablePackage,\n\n        [string] $AssetName = \"*\",\n\n        [string] $AssetVersion = \"*\",\n\n        [string] $AssetFilename = \"*\",\n\n        [string] $AssetDescription = \"*\",\n\n        [string] $AssetId = \"*\",\n        \n        [Alias('Token')]\n        [string] $BearerToken = $Script:LcsApiBearerToken,\n\n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [Alias('GetLatest')]\n        [switch] $Latest,\n\n        [switch] $SkipSasGeneration,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    Invoke-TimeSignal -Start\n\n    if (-not ($BearerToken.StartsWith(\"Bearer \"))) {\n        $BearerToken = \"Bearer $BearerToken\"\n    }\n\n    $colTemp = Get-LcsSharedAssetFile -BearerToken $BearerToken -LcsApiUri $LcsApiUri -FileType $([int]$FileType) -RetryTimeout $RetryTimeout\n\n    $assets = $colTemp | Select-PSFObject -TypeName \"D365FO.TOOLS.Lcs.Asset.File\" -Property \"*\", \"Id as AssetId\", `\n    @{Name = \"ProductVersion\"; Expression = { [System.Version]$($_.Name.Split(\" \") | Select-Object -Last 1 ) } }, `\n    @{Name = \"ProductBuild\"; Expression = { [System.Version]$($_.FileName.Split(\"_\") | Select-Object -First 1 -Skip 1) } }\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    if ($Latest) {\n        $latestSharedAsset = $assets | Sort-Object -Property \"ModifiedDate\" -Descending | Select-Object -First 1\n\n        if ($SkipSasGeneration -eq $false) {\n            $latestSharedAsset = Get-LcsFileAsset -BearerToken $BearerToken -ProjectId $ProjectId -LcsApiUri $LcsApiUri -AssetId $latestSharedAsset.Id -RetryTimeout $RetryTimeout\n            $latestSharedAsset | Select-PSFObject -TypeName \"D365FO.TOOLS.Lcs.Asset.File\" -Property \"*\", \"Id as AssetId\", `\n            @{Name = \"ProductVersion\"; Expression = { [System.Version]$($_.Name.Split(\" \") | Select-Object -Last 1 ) } }, `\n            @{Name = \"ProductBuild\"; Expression = { [System.Version]$($_.FileName.Split(\"_\") | Select-Object -First 1 -Skip 1) } }\n        }\n        else {\n            $latestSharedAsset\n        }\n    }\n    else {\n        foreach ($obj in $assets) {\n            if ($obj.Name -NotLike $AssetName) { continue }\n            if ($obj.Version -NotLike $AssetVersion) { continue }\n            if ($obj.FileName -NotLike $AssetFilename) { continue }\n            if ($obj.FileDescription -NotLike $AssetDescription) { continue }\n            if ($obj.Id -NotLike $AssetId) { continue }\n\n            if ($SkipSasGeneration -eq $false) {\n                $obj = Get-LcsFileAsset -BearerToken $BearerToken -ProjectId $ProjectId -LcsApiUri $LcsApiUri -AssetId $obj.Id -RetryTimeout $RetryTimeout\n                $obj | Select-PSFObject -TypeName \"D365FO.TOOLS.Lcs.Asset.File\" -Property \"*\", \"Id as AssetId\", `\n                @{Name = \"ProductVersion\"; Expression = { [System.Version]$($_.Name.Split(\" \") | Select-Object -Last 1 ) } }, `\n                @{Name = \"ProductBuild\"; Expression = { [System.Version]$($_.FileName.Split(\"_\") | Select-Object -First 1 -Skip 1) } }\n            }\n            else {\n                $obj\n            }\n        }\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365maintenancemode.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the maintenance mode status of the environment\n        \n    .DESCRIPTION\n        Get the maintenance mode status of the Dynamics 365 environment to make sure that things are in the correct state\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .EXAMPLE\n        PS C:\\> Get-D365MaintenanceMode\n        \n        This will get the current state of the maintenance mode of the environment\n        \n    .NOTES\n        Tags: MaintenanceMode, Maintenance, License, Configuration, Servicing\n        \n        Author: Mötz Jensen (@splaxi)\n        \n    .LINK\n        Enable-D365MaintenanceMode\n        \n    .LINK\n        Disable-D365MaintenanceMode\n#>\nfunction Get-D365MaintenanceMode {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 3 )]\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 4 )]\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 5 )]\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 6 )]\n        [string] $SqlPwd = $Script:DatabaseUserPassword\n    )\n\n        Write-PSFMessage -Level Verbose -Message \"Getting Maintenance Mode using SQL scripts.\"\n\n        $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n    $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd\n    }\n\n    $sqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n\n    $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\get-maintenancemode.sql\") -join [Environment]::NewLine\n\n    try {\n        $sqlCommand.Connection.Open()\n    \n        $reader = $sqlCommand.ExecuteReader()\n\n        while ($reader.Read() -eq $true) {\n            [PSCustomObject]@{\n                MaintenanceModeEnabled          = [bool][int]\"$($reader.GetString($($reader.GetOrdinal(\"VALUE\"))))\"\n            }\n        }\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n    finally {\n        $reader.close()\n\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365model.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get available model from Dynamics 365 Finance & Operations environment\n        \n    .DESCRIPTION\n        Get available model from the machine running the AOS service for Dynamics 365 Finance & Operations\n        \n    .PARAMETER Name\n        Name of the model that you are looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"Application*Adaptor\"\n        \n        Default value is \"*\" which will search for all models\n        \n    .PARAMETER Module\n        Name of the module that you want to list models from\n        \n        Accepts wildcards for searchinf. E.g. -Module \"Application*Adaptor\"\n        \n        Default value is \"*\" which will search across all modules\n        \n    .PARAMETER CustomizableOnly\n        Instructs the cmdlet to filter out all models that cannot be customized\n        \n    .PARAMETER ExcludeMicrosoftModels\n        Instructs the cmdlet to exclude all models that has Microsoft as the publisher from the output\n        \n    .PARAMETER ExcludeBinaryModels\n        Instruct the cmdlet to exclude binary models from the output\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the AOS service PackagesLocalDirectory\\bin\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Default path is the same as the AOS service \"PackagesLocalDirectory\" directory\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Model\n        \n        Shows the entire list of installed models located in the default location on the machine.\n        \n        A result set example:\n        \n        ModelName                      Module                         IsBinary Customization        Id Publisher\n        ---------                      ------                         -------- -------------        -- ---------\n        AccountsPayableMobile          AccountsPayableMobile          False    DoNotAllow    895571380 Microsoft Corporation\n        ApplicationCommon              ApplicationCommon              False    DoNotAllow      8956718 Microsoft\n        ApplicationFoundation          ApplicationFoundation          False    Allow               450 Microsoft Corporation\n        IsvFoundation                  IsvFoundation                  True     Allow         895972027 Isv Corp\n        IsvLicense                     IsvLicense                     True     DoNotAllow    895972028 Isv Corp\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Model -CustomizableOnly\n        \n        Shows only the models that are marked as customizable.\n        Will only include models that is Customization = \"Allow\".\n        \n        A result set example:\n        \n        ModelName                      Module                         IsBinary Customization        Id Publisher\n        ---------                      ------                         -------- -------------        -- ---------\n        ApplicationFoundation          ApplicationFoundation          False    Allow               450 Microsoft Corporation\n        ApplicationPlatform            ApplicationPlatform            False    Allow               400 Microsoft Corporation\n        ApplicationPlatformFormAdaptor ApplicationPlatformFormAdaptor False    Allow            855030 Microsoft Corporation\n        IsvFoundation                  IsvFoundation                  True     Allow         895972027 Isv Corp\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Model -ExcludeMicrosoftModels\n        \n        Shows only the models that doesn't have \"Microsoft\" in the publisher.\n        Will only include models that is Publisher -NotLike \"Microsoft*\".\n        \n        A result set example:\n        \n        ModelName                      Module                         IsBinary Customization        Id Publisher\n        ---------                      ------                         -------- -------------        -- ---------\n        IsvFoundation                  IsvFoundation                  True     Allow         895972027 Isv Corp\n        IsvLicense                     IsvLicense                     True     DoNotAllow    895972028 Isv Corp\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Model -ExcludeBinaryModels\n        \n        Shows only the models that are NOT binary.\n        Will only include models that is IsBinary = \"False\".\n        \n        A result set example:\n        \n        ModelName                      Module                         IsBinary Customization        Id Publisher\n        ---------                      ------                         -------- -------------        -- ---------\n        AccountsPayableMobile          AccountsPayableMobile          False    DoNotAllow    895571380 Microsoft Corporation\n        ApplicationCommon              ApplicationCommon              False    DoNotAllow      8956718 Microsoft\n        ApplicationFoundation          ApplicationFoundation          False    Allow               450 Microsoft Corporation\n        \n        \n    .EXAMPLE\n        PS C:\\> Get-D365Model -CustomizableOnly -ExcludeMicrosoftModels\n        \n        Shows only the models that are marked as customizable and NOT from Microsoft.\n        Will only include models that is Customization = \"Allow\".\n        Will only include models that is Publisher -NotLike \"Microsoft*\".\n        \n        A result set example:\n        \n        ModelName                      Module                         IsBinary Customization        Id Publisher\n        ---------                      ------                         -------- -------------        -- ---------\n        IsvFoundation                  IsvFoundation                  True     Allow         895972027 Isv Corp\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Model -Name \"Application*Adaptor\"\n        \n        Shows the list of models where the name fits the search \"Application*Adaptor\".\n        \n        A result set example:\n        \n        ModelName                      Module                         IsBinary Customization        Id Publisher\n        ---------                      ------                         -------- -------------        -- ---------\n        ApplicationFoundationFormAd... ApplicationFoundationFormAd... False    DoNotAllow       855029 Microsoft Corporation\n        ApplicationPlatformFormAdaptor ApplicationPlatformFormAdaptor False    Allow            855030 Microsoft Corporation\n        ApplicationSuiteFormAdaptor    ApplicationSuiteFormAdaptor    False    DoNotAllow       855028 Microsoft Corporation\n        ApplicationWorkspacesFormAd... ApplicationWorkspacesFormAd... False    DoNotAllow       855066 Microsoft Corporation\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Model -Module ApplicationSuite\n        \n        Shows only the models that are inside the ApplicationSuite module.\n        \n        A result set example:\n        \n        ModelName                      Module                         IsBinary Customization        Id Publisher\n        ---------                      ------                         -------- -------------        -- ---------\n        Electronic Reporting Applic... ApplicationSuite               False    DoNotAllow       855009 Microsoft Corporation\n        Foundation                     ApplicationSuite               False    DoNotAllow           17 Microsoft Corporation\n        SCMControls                    ApplicationSuite               False    DoNotAllow       855891 Microsoft Corporation\n        Tax Books Application Suite... ApplicationSuite               False    DoNotAllow    895570102 Microsoft Corporation\n        Tax Engine Application Suit... ApplicationSuite               False    DoNotAllow      8957001 Microsoft Corporation\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Model -Name \"*Application*\" -Module \"*Suite*\"\n        \n        Shows the list of models where the name fits the search \"*Application*\" and the module name fits the search \"*Suite*\".\n        \n        A result set example:\n        \n        ModelName                      Module                         IsBinary Customization        Id Publisher\n        ---------                      ------                         -------- -------------        -- ---------\n        ApplicationSuiteFormAdaptor    ApplicationSuiteFormAdaptor    False    DoNotAllow       855028 Microsoft Corporation\n        AtlApplicationSuite            AtlApplicationSuite            False    DoNotAllow    895972466 Microsoft Corporation\n        Electronic Reporting Applic... ApplicationSuite               False    DoNotAllow       855009 Microsoft Corporation\n        Tax Books Application Suite... ApplicationSuite               False    DoNotAllow    895570102 Microsoft Corporation\n        Tax Engine Application Suit... ApplicationSuite               False    DoNotAllow      8957001 Microsoft Corporation\n        \n    .NOTES\n        Tags: PackagesLocalDirectory, Servicing, Model, Models, Module, Modules\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        Author: Martin Dráb (@goshoom)\n        \n        The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages.\n        \n#>\nfunction Get-D365Model {\n    [CmdletBinding()]\n    param (\n        [string] $Name = \"*\",\n\n        [Parameter(ValueFromPipelineByPropertyName = $true)]\n        [Alias(\"ModuleName\")]\n        [string] $Module = \"*\",\n\n        [switch] $CustomizableOnly,\n        \n        [switch] $ExcludeMicrosoftModels,\n\n        [switch] $ExcludeBinaryModels,\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    begin {\n        [System.Collections.ArrayList] $Files2Process = New-Object -TypeName \"System.Collections.ArrayList\"\n        \n        $null = $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Management.Delta.dll\"))\n        $null = $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Management.Diff.dll\"))\n        $null = $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Management.Merge.dll\"))\n        $null = $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Management.Core.dll\"))\n        $null = $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.dll\"))\n        $null = $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Core.dll\"))\n        $null = $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Storage.dll\"))\n        $null = $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll\"))\n\n        Import-AssemblyFileIntoMemory -Path $($Files2Process.ToArray())\n\n        Write-PSFMessage -Level Verbose -Message \"Intializing RuntimeProvider.\"\n\n        $runtimeProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.Runtime.RuntimeProviderConfiguration -ArgumentList $PackageDirectory\n        $metadataProviderFactoryViaRuntime = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProviderViaRuntime = $metadataProviderFactoryViaRuntime.CreateRuntimeProvider($runtimeProviderConfiguration)\n\n        Write-PSFMessage -Level Verbose -Message \"MetadataProvider initialized.\" -Target $metadataProviderViaRuntime\n\n        $models = $metadataProviderViaRuntime.ModelManifest.ListModelInfos()\n        $models | ForEach-Object {\n            $_ | Add-Member -MemberType NoteProperty -Name 'IsBinary' -Value $false\n        }\n\n        Write-PSFMessage -Level Verbose -Message \"Testing if the cmdlet is running on a OneBox or not.\" -Target $Script:IsOnebox\n    \n        if ($Script:IsOnebox) {\n            Write-PSFMessage -Level Verbose -Message \"Machine is onebox. Initializing DiskProvider too.\"\n\n            $diskProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n            $diskProviderConfiguration.AddMetadataPath($PackageDirectory)\n            $metadataProviderFactoryViaDisk = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n            $metadataProviderViaDisk = $metadataProviderFactoryViaDisk.CreateDiskProvider($diskProviderConfiguration)\n\n            Write-PSFMessage -Level Verbose -Message \"MetadataProvider initialized.\" -Target $metadataProviderViaDisk\n\n            $diskModels = $metadataProviderViaDisk.ModelManifest.ListModelInfos()\n\n            foreach ($model in $models) {\n                if ($diskModels.Name -NotContains $model.Name) {\n                    $model.IsBinary = $true\n                }\n            }\n\n            $uncompiledModels = @(\n                foreach ($model in $diskModels) {\n                    if ($models.Name -NotContains $model.Name) {\n                        $model | Add-Member -MemberType NoteProperty -Name 'IsBinary' -Value $false\n                        $model\n                    }\n                }\n            )\n\n            # Combined both arrays\n            $models = $models + $uncompiledModels\n        }\n\n        if ($CustomizableOnly) {\n            $models = $models | Where-Object Customization -eq \"Allow\"\n        }\n\n        if ($ExcludeBinaryModels -eq $true) {\n            $models = $models | Where-Object IsBinary -eq $false\n        }\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        $modelsLocal = $models\n        \n        $modelsLocal = $modelsLocal | Where-Object Module -like $Module\n\n        Write-PSFMessage -Level Verbose -Message \"Looping through all models.\"\n\n        foreach ($obj in $($modelsLocal | Sort-Object Name, Module)) {\n            Write-PSFMessage -Level Verbose -Message \"Filtering out all models that doesn't match the model search.\" -Target $obj\n            if ($obj.Name -NotLike $Name) { continue }\n\n            if ($ExcludeMicrosoftModels -and $obj.Publisher -like \"Microsoft*\") { continue }\n            \n            $obj | Select-PSFObject \"Name as ModelName\", * -ExcludeProperty Name -TypeName \"D365FO.TOOLS.ModelInfo\"\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365module.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get installed package / module from Dynamics 365 Finance & Operations environment\n        \n    .DESCRIPTION\n        Get installed package / module from the machine running the AOS service for Dynamics 365 Finance & Operations\n        \n    .PARAMETER Name\n        Name of the package / module that you are looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"Application*Adaptor\"\n        \n        Default value is \"*\" which will search for all packages / modules\n        \n    .PARAMETER ExcludeBinaryModules\n        Instruct the cmdlet to exclude binary modules from the output\n        \n    .PARAMETER InDependencyOrder\n        Instructs the cmdlet to return modules in dependency order, starting with modules\n        with no references to other modules.\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the AOS service PackagesLocalDirectory\\bin\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Module\n        \n        Shows the entire list of installed packages / modules located in the default location on the machine.\n        \n        A result set example:\n        \n        ModuleName                               IsBinary Version         References\n        ----------                               -------- -------         ----------\n        AccountsPayableMobile                    False    10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli...\n        ApplicationCommon                        False    10.0.8008.26462 {ApplicationFoundation, ApplicationPlatform}\n        ApplicationFoundation                    False    7.0.5493.35504  {ApplicationPlatform}\n        ApplicationFoundationFormAdaptor         False    7.0.4841.35227  {ApplicationPlatform, ApplicationFoundation, TestE...\n        Custom                                   True     10.0.0.0        {ApplicationPlatform}\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Module -ExcludeBinaryModules\n        \n        Outputs the all packages / modules that are NOT binary.\n        Will only include modules that is IsBinary = \"False\".\n        \n        A result set example:\n        \n        ModuleName                               IsBinary Version         References\n        ----------                               -------- -------         ----------\n        AccountsPayableMobile                    False    10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli...\n        ApplicationCommon                        False    10.0.8008.26462 {ApplicationFoundation, ApplicationPlatform}\n        ApplicationFoundation                    False    7.0.5493.35504  {ApplicationPlatform}\n        ApplicationFoundationFormAdaptor         False    7.0.4841.35227  {ApplicationPlatform, ApplicationFoundation, TestE...\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Module -InDependencyOrder\n        \n        Return packages / modules in dependency order, starting with modules with no references to other modules.\n        \n        A result set example:\n        \n        ModuleName                               IsBinary Version         References\n        ----------                               -------- -------         ----------\n        ApplicationPlatform                      False    7.0.0.0         {}\n        ApplicationFoundation                    False    7.0.0.0         {ApplicationPlatform}\n        ApplicationCommon                        False    10.21.36.8818   {ApplicationFoundation, ApplicationPlatform}\n        AppTroubleshootingCore                   False    10.21.1136.2... {ApplicationCommon, ApplicationFoundation, Applica...\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Module -Name \"Application*Adaptor\"\n        \n        Shows the list of installed packages / modules where the name fits the search \"Application*Adaptor\".\n        \n        A result set example:\n        \n        ModuleName                               IsBinary Version         References\n        ----------                               -------- -------         ----------\n        ApplicationFoundationFormAdaptor         False    7.0.4841.35227  {ApplicationPlatform, ApplicationFoundation, TestE...\n        ApplicationPlatformFormAdaptor           False    7.0.4841.35227  {ApplicationPlatform, TestEssentials}\n        ApplicationSuiteFormAdaptor              False    10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli...\n        ApplicationWorkspacesFormAdaptor         False    10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli...\n        \n    .NOTES\n        Tags: PackagesLocalDirectory, Servicing, Model, Models, Package, Packages\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        Author: Martin Dráb (@goshoom)\n        \n        The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages.\n        \n#>\nfunction Get-D365Module {\n    [CmdletBinding()]\n    param (\n        [string] $Name = \"*\",\n\n        [switch] $ExcludeBinaryModules,\n\n        [Alias(\"Dependency\")]\n        [switch] $InDependencyOrder,\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    begin {\n        [System.Collections.ArrayList] $Files2Process = New-Object -TypeName \"System.Collections.ArrayList\"\n        \n        $null = $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Management.Delta.dll\"))\n        $null = $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Management.Diff.dll\"))\n        $null = $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Management.Merge.dll\"))\n        $null = $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Management.Core.dll\"))\n        $null = $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.dll\"))\n        $null = $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Core.dll\"))\n        $null = $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Storage.dll\"))\n        $null = $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll\"))\n\n        Import-AssemblyFileIntoMemory -Path $($Files2Process.ToArray())\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n\n        Write-PSFMessage -Level Verbose -Message \"Intializing RuntimeProvider.\"\n\n        $runtimeProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.Runtime.RuntimeProviderConfiguration -ArgumentList $PackageDirectory\n        $metadataProviderFactoryViaRuntime = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProviderViaRuntime = $metadataProviderFactoryViaRuntime.CreateRuntimeProvider($runtimeProviderConfiguration)\n\n        Write-PSFMessage -Level Verbose -Message \"MetadataProvider initialized.\" -Target $metadataProviderViaRuntime\n\n        try {\n            $modules = $metadataProviderViaRuntime.ModelManifest.ListModulesInDependencyOrder()\n        } catch {\n            Write-PSFMessage -Level Warning -Message \"Failed to retrieve runtime modules in dependency order. Falling back to ListModules().\" -Target $metadataProviderViaRuntime\n            $modules = $metadataProviderViaRuntime.ModelManifest.ListModules()\n        }\n\n        $modules | ForEach-Object {\n            $_ | Add-Member -MemberType NoteProperty -Name 'IsBinary' -Value $false\n        }\n\n        Write-PSFMessage -Level Verbose -Message \"Testing if the cmdlet is running on a OneBox or not.\" -Target $Script:IsOnebox\n    \n        if ($Script:IsOnebox) {\n            Write-PSFMessage -Level Verbose -Message \"Machine is onebox. Initializing DiskProvider too.\"\n\n            $diskProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n            $diskProviderConfiguration.AddMetadataPath($PackageDirectory)\n            $metadataProviderFactoryViaDisk = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n            $metadataProviderViaDisk = $metadataProviderFactoryViaDisk.CreateDiskProvider($diskProviderConfiguration, $metadataProviderViaRuntime.ModelManifest)\n\n            Write-PSFMessage -Level Verbose -Message \"MetadataProvider initialized.\" -Target $metadataProviderViaDisk\n\n            try {\n                $diskModules = $metadataProviderViaDisk.ModelManifest.ListModulesInDependencyOrder()\n            } catch {\n                Write-PSFMessage -Level Warning -Message \"Failed to retrieve disk modules in dependency order. Falling back to ListModules().\" -Target $metadataProviderViaDisk\n                $diskModules = $metadataProviderViaDisk.ModelManifest.ListModules()\n            }\n\n            foreach ($module in $modules) {\n                if ($diskModules.Name -NotContains $module.Name) {\n                    $module.IsBinary = $true\n                }\n            }\n            \n            $uncompiledModules = @(\n                foreach ($module in $diskModules) {\n                    if ($modules.Name -NotContains $module.Name) {\n                        $module | Add-Member -MemberType NoteProperty -Name 'IsBinary' -Value $false\n                        $module\n                    }\n                }\n            )\n\n            # Combined both arrays\n            $modules = $modules + $uncompiledModules\n        }\n\n        if ($ExcludeBinaryModules -eq $true) {\n            $modules = $modules | Where-Object IsBinary -eq $false\n        }\n\n        if ($InDependencyOrder -eq $false) {\n            $modules = $modules | Sort-Object Name\n        }\n\n        Write-PSFMessage -Level Verbose -Message \"Looping through all modules.\"\n\n        foreach ($obj in $modules) {\n            Write-PSFMessage -Level Verbose -Message \"Filtering out all modules that doesn't match the model search.\" -Target $obj\n            if ($obj.Name -NotLike $Name) { continue }\n\n            $moduleName = $obj.Name\n\n            $res = [Ordered]@{\n                Module     = $moduleName\n                ModuleName = $moduleName\n                IsBinary   = $obj.IsBinary\n                PSTypeName = 'D365FO.TOOLS.ModuleInfo'\n            }\n\n            $moduleAssemblyPath = Join-Path $PackageDirectory \"$moduleName\\bin\\Dynamics.AX.$moduleName.dll\"\n\n            if (Test-Path -Path $moduleAssemblyPath) {\n                $fileVersion = Get-FileVersion -Path $moduleAssemblyPath\n                $version = $fileVersion.FileVersion\n                $versionUpdated = $fileVersion.FileVersionUpdated\n            }\n            else {\n                $version = \"\"\n                $versionUpdated = \"\"\n            }\n\n            $res.Version = $version\n            $res.VersionUpdated = $versionUpdated\n            $res.References = $obj.References\n            \n            [PSCustomObject]$res\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365offlineauthenticationadminemail.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Gets the registered offline administrator e-mail configured\n        \n    .DESCRIPTION\n        Get the registered offline administrator from the \"DynamicsDevConfig.xml\" file located in the default Package Directory\n        \n    .EXAMPLE\n        PS C:\\> Get-D365OfflineAuthenticationAdminEmail\n        \n        Will read the DynamicsDevConfig.xml and display the registered Offline Administrator E-mail address.\n        \n    .NOTES\n        Tags: Development, Email, DynamicsDevConfig, Offline, Authentication\n        \n        This cmdlet is inspired by the work of \"Sheikh Sohail Hussain\" (twitter: @SSohailHussain)\n        \n        His blog can be found here:\n        http://d365technext.blogspot.com\n        \n        The specific blog post that we based this cmdlet on can be found here:\n        http://d365technext.blogspot.com/2018/07/offline-authentication-admin-email.html\n#>\nfunction Get-D365OfflineAuthenticationAdminEmail {\n    [CmdletBinding()]\n    param ()\n\n    $filePath = Join-Path (Join-Path $Script:PackageDirectory \"bin\") \"DynamicsDevConfig.xml\"\n\n    if(-not (Test-PathExists -Path $filePath -Type Leaf)) {return}\n\n    $namespace = @{ns=\"http://schemas.microsoft.com/dynamics/2012/03/development/configuration\"}\n    $OfflineAuthAdminEmail = Select-Xml -XPath \"/ns:DynamicsDevConfig/ns:OfflineAuthenticationAdminEmail\" -Path $filePath -Namespace $namespace\n\n    $AdminEmail = $OfflineAuthAdminEmail.Node.InnerText\n    [PSCustomObject] @{Email = $AdminEmail}\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365packagebundledetail.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the details from an axscdppkg file\n        \n    .DESCRIPTION\n        Get the details from an axscdppkg file by extracting it like a zip file.\n        \n        Capable of extracting the manifest details from the inner packages as well\n        \n    .PARAMETER Path\n        Path to the axscdppkg file you want to analyze\n        \n    .PARAMETER ExtractionPath\n        Path where you want the cmdlet to work with extraction of all the files\n        \n        Default value is: C:\\Users\\Username\\AppData\\Local\\Temp\n        \n    .PARAMETER KB\n        KB number of the hotfix that you are looking for\n        \n        Accepts wildcards for searching. E.g. -KB \"4045*\"\n        \n        Default value is \"*\" which will search for all KB's\n        \n    .PARAMETER Hotfix\n        Package Id / Hotfix number the hotfix that you are looking for\n        \n        Accepts wildcards for searching. E.g. -Hotfix \"7045*\"\n        \n        Default value is \"*\" which will search for all hotfixes\n        \n    .PARAMETER Traverse\n        Switch to instruct the cmdlet to traverse the inner packages and extract their details\n        \n    .PARAMETER KeepFiles\n        Switch to instruct the cmdlet to keep the files for further manual analyze\n        \n    .PARAMETER IncludeRawManifest\n        Switch to instruct the cmdlet to include the raw content of the manifest file\n        \n        Only works with the -Traverse option\n        \n    .EXAMPLE\n        PS C:\\> Get-D365PackageBundleDetail -Path \"c:\\temp\\HotfixPackageBundle.axscdppkg\" -Traverse\n        \n        This will extract all the content from the \"HotfixPackageBundle.axscdppkg\" file and extract all inner packages. For each inner package it will find the manifest file and fetch the KB numbers. The raw manifest file content is included to be analyzed.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365PackageBundleDetail -Path \"c:\\temp\\HotfixPackageBundle.axscdppkg\" -ExtractionPath C:\\Temp\\20180905 -Traverse -KeepFiles\n        \n        This will extract all the content from the \"HotfixPackageBundle.axscdppkg\" file and extract all inner packages. It will extract the content into C:\\Temp\\20180905 and keep the files after completion.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365PackageBundleDetail -Path C:\\temp\\HotfixPackageBundle.axscdppkg -Traverse -IncludeRawManifest\n        \n        This is an advanced scenario.\n        \n        This will traverse the \"HotfixPackageBundle.axscdppkg\" file and will include the raw manifest file details in the output.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365PackageBundleDetail -Path C:\\temp\\HotfixPackageBundle.axscdppkg -Traverse -IncludeRawManifest | ForEach-Object {$_.RawManifest | Out-File \"C:\\temp\\$($_.PackageId).txt\"}\n        \n        This is an advanced scenario.\n        \n        This will traverse the \"HotfixPackageBundle.axscdppkg\" file and save the manifest files into c:\\temp. Everything else is omitted and cleaned up.\n        \n    .NOTES\n        Tags: Hotfix, KB, Manifest, HotfixPackageBundle, axscdppkg, Package, Bundle, Deployable\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-D365PackageBundleDetail {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $True)]\n        [Alias('File')]\n        [string] $Path,\n\n        [string] $ExtractionPath = ([System.IO.Path]::GetTempPath()),\n\n        [string] $KB = \"*\",\n\n        [string] $Hotfix = \"*\",\n\n        [switch] $Traverse,\n\n        [switch] $KeepFiles,\n\n        [switch] $IncludeRawManifest\n    )\n    \n    begin {\n        Invoke-TimeSignal -Start\n\n        if (!(Test-Path -Path $Path -PathType Leaf)) {\n            Write-PSFMessage -Level Host -Message \"The <c='em'>$Path</c> file wasn't found. Please ensure the file <c='em'>exists </c> and you have enough <c='em'>permission/c> to access the file.\"\n            Stop-PSFFunction -Message \"Stopping because a file is missing.\"\n            return\n        }\n\n        Unblock-File -Path $Path\n\n        if(!(Test-Path -Path $ExtractionPath)) {\n            Write-PSFMessage -Level Verbose -Message \"The extract path didn't exists. Creating it.\" -Target $ExtractionPath\n            $null = New-Item -Path $ExtractionPath -Force -ItemType Directory\n        }\n\n        if ($Path -notlike \"*.zip\") {\n            $tempPathZip = Join-Path $ExtractionPath \"$($(New-Guid).ToString()).zip\"\n\n            Write-PSFMessage -Level Verbose -Message \"The file isn't a zip file. Copying the file to $tempPathZip\" -Target $tempPathZip\n            Copy-Item -Path $Path -Destination $tempPathZip -Force\n            $Path = $tempPathZip\n        }\n\n        $packageTemp = Join-Path $ExtractionPath ((Get-Random -Maximum 99999).ToString())\n\n        $oldprogressPreference = $global:progressPreference\n        $global:progressPreference = 'silentlyContinue'\n\n    }\n    \n    process {\n        if (Test-PSFFunctionInterrupt) {return}\n\n        Write-PSFMessage -Level Verbose -Message \"Extracting the zip file to $packageTemp\" -Target $packageTemp\n        Expand-Archive -Path $Path -DestinationPath $packageTemp\n\n        if ($Traverse) {\n            $files = Get-ChildItem -Path $packageTemp -Filter \"*.axscdp\"\n            \n            foreach ($item in $files) {\n                $filename = [System.IO.Path]::GetFileNameWithoutExtension($item.Name)\n                $tempFile = Join-Path $packageTemp \"$filename.zip\"\n        \n                Write-PSFMessage -Level Verbose -Message \"Coping $($item.FullName) to $tempFile\" -Target $tempFile\n                Copy-Item -Path $item.FullName -Destination $tempFile\n\n                $tempDir = (Join-Path $packageTemp ($filename.Replace(\"DynamicsAX_\", \"\")))\n                $null = New-Item -Path $tempDir -ItemType Directory -Force\n\n                Write-PSFMessage -Level Verbose -Message \"Extracting the zip file $tempFile to $tempDir\" -Target $tempDir\n                Expand-Archive -Path $tempFile -DestinationPath $tempDir\n            }\n\n            $manifestFiles = Get-ChildItem -Path $packageTemp -Recurse -Filter \"PackageManifest.xml\"\n\n            $namespace = @{ns = \"http://schemas.datacontract.org/2004/07/Microsoft.Dynamics.AX.Servicing.SCDP.Packaging\";\n                           nsKB = \"http://schemas.microsoft.com/2003/10/Serialization/Arrays\"}\n\n            Write-PSFMessage -Level Verbose -Message \"Getting all the information from the manifest file\"\n\n            foreach ($item in $manifestFiles) {\n                $raw = (Get-Content -Path $item.FullName) -join [Environment]::NewLine\n                $xmlDoc = [xml]$raw\n                $kbs = Select-Xml -Xml $xmlDoc -XPath \"//ns:UpdatePackageManifest/ns:KBNumbers/nsKB:string\" -Namespace $namespace\n                $packageId = Select-Xml -Xml $xmlDoc -XPath \"//ns:UpdatePackageManifest/ns:PackageId/ns:PackageId\" -Namespace $namespace\n                \n                $strPackage = $packageId.Node.InnerText\n                $arrKbs = $kbs.node.InnerText\n\n                if($packageId.Node.InnerText -notlike $Hotfix) {continue}\n                if(@($arrKbs) -notlike $KB) {continue} #* Search across an array with like\n\n                $Obj = [PSCustomObject]@{Hotfix = $strPackage\n                KBs = ($arrKbs -Join \";\")}\n\n                if($IncludeRawManifest) {$Obj.RawManifest = $raw}\n\n                $Obj | Select-PSFObject -TypeName \"D365FO.TOOLS.PackageBundleManifestDetail\"\n            }\n        }\n        else {\n            Get-ChildItem -Path $packageTemp -Filter \"*.*\" | Select-PSFObject -TypeName \"D365FO.TOOLS.PackageBundleDetail\" \"BaseName as Name\"\n        }\n    }\n    \n    end {\n        if(!$Keepfiles) {\n            Remove-Item -Path $packageTemp -Recurse -Force -ErrorAction SilentlyContinue\n\n            if(![system.string]::IsNullOrEmpty($tempPathZip)) {\n                Remove-Item -Path $tempPathZip -Recurse -Force -ErrorAction SilentlyContinue\n            }\n        }\n\n        $global:progressPreference = $oldprogressPreference\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365packagelabelresourcefile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get label / resource file from a package\n        \n    .DESCRIPTION\n        Get label (resource) file from the package directory of a Dynamics 365 Finance & Operations environment\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed packages\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .PARAMETER Name\n        Name of the label (resource) file you are looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"Fixed*Accounting\"\n        \n        Default value is \"*\" which will search for all label files\n        \n    .PARAMETER Language\n        The language of the label file you are looking for\n        \n        Accepts wildcards for searching. E.g. -Language \"en*\"\n        \n        Default value is \"en-US\" which will search for en-US language files\n        \n    .EXAMPLE\n        PS C:\\> Get-D365PackageLabelResourceFile -PackageDirectory \"C:\\AOSService\\PackagesLocalDirectory\\ApplicationSuite\"\n        \n        Shows all the label files for ApplicationSuite package\n        \n    .EXAMPLE\n        PS C:\\> Get-D365PackageLabelResourceFile -PackageDirectory \"C:\\AOSService\\PackagesLocalDirectory\\ApplicationSuite\" -Name \"Fixed*Accounting\"\n        \n        Shows the label files for ApplicationSuite package where the name fits the search \"Fixed*Accounting\"\n        \n    .EXAMPLE\n        PS C:\\> Get-D365InstalledPackage -Name \"ApplicationSuite\" | Get-D365PackageLabelResourceFile\n        \n        Shows all label files (en-US) for the ApplicationSuite package\n        \n    .NOTES\n        Tags: PackagesLocalDirectory, Label, Labels, Language, Development, Servicing, Module, Package, Packages\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages.\n#>\nfunction Get-D365PackageLabelResourceFile {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true)]\n        [Parameter(Mandatory = $true, ParameterSetName = 'Specific')]\n        [Alias('Path')]\n        [string] $PackageDirectory,\n\n        [string] $Name = \"*\",\n\n        [string] $Language = \"en-US\"\n    )\n\n    BEGIN {}\n\n    PROCESS {\n        $Path = $PackageDirectory\n\n        if (Test-Path \"$Path\\Resources\\$Language\") {\n        \n            $files = Get-ChildItem -Path (\"$Path\\Resources\\$Language\\*.resources.dll\")\n\n            foreach ($obj in $files) {\n                if ($obj.Name.Replace(\".resources.dll\", \"\") -NotLike $Name) { continue }\n                [PSCustomObject]@{\n                    LabelName    = ($obj.Name).Replace(\".resources.dll\", \"\")\n                    LanguageName = (Get-Command $obj.FullName).FileVersionInfo.Language\n                    Language     = $obj.directory.basename\n                    FilePath     = $obj.FullName\n                }\n            }\n        }\n        else {\n            Write-PSFMessage -Level Verbose -Message \"Skipping `\"$(\"$Path\\Resources\\$Language\")`\" because it doesn't exist.\"\n        }\n    }\n\n    END {}\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365packagelabelresources.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get label from the resource file\n        \n    .DESCRIPTION\n        Get label details from the resource file for a Dynamics 365 Finance & Operations environment\n        \n    .PARAMETER FilePath\n        The path to resource file that you want to get label details from\n        \n    .PARAMETER Name\n        Name of the label you are looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"@PRO*\"\n        \n        Default value is \"*\" which will search for all labels in the resource file\n        \n    .PARAMETER Value\n        Value of the label you are looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"*Qty*\"\n        \n        Default value is \"*\" which will search for all values in the resource file\n        \n    .PARAMETER IncludePath\n        Switch to indicate whether you want the result set to include the path to the resource file or not\n        \n        Default is OFF - path details will not be part of the output\n        \n    .EXAMPLE\n        PS C:\\> Get-D365PackageLabelResources -Path \"C:\\AOSService\\PackagesLocalDirectory\\ApplicationSuite\\Resources\\en-US\\PRO.resources.dll\"\n        \n        Will get all labels from the \"PRO.resouce.dll\" file\n        \n        The language is determined by the path to the resource file and nothing else\n        \n    .EXAMPLE\n        PS C:\\> Get-D365PackageLabelResources -Path \"C:\\AOSService\\PackagesLocalDirectory\\ApplicationSuite\\Resources\\en-US\\PRO.resources.dll\" -Name \"@PRO505\"\n        \n        Will get the label with the name \"@PRO505\" from the \"PRO.resouce.dll\" file\n        \n        The language is determined by the path to the resource file and nothing else\n        \n    .EXAMPLE\n        PS C:\\> Get-D365PackageLabelResources -Path \"C:\\AOSService\\PackagesLocalDirectory\\ApplicationSuite\\Resources\\en-US\\PRO.resources.dll\" -Value \"*qty*\"\n        \n        Will get all the labels where the value fits the search \"*qty*\" from the \"PRO.resouce.dll\" file\n        \n        The language is determined by the path to the resource file and nothing else\n        \n    .EXAMPLE\n        PS C:\\> Get-D365InstalledPackage -Name \"ApplicationSuite\" | Get-D365PackageLabelResourceFile -Language \"da\" | Get-D365PackageLabelResources -value \"*batch*\" -IncludePath\n        \n        Will get all the labels, across all label files, for the \"ApplicationSuite\", where the language is \"da\" and where the label value fits the search \"*batch*\".\n        \n        The path to the label file is included in the output.\n        \n    .NOTES\n        Tags: PackagesLocalDirectory, Label, Labels, Language, Development, Servicing, Resource, Resources\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        There are several advanced scenarios for this cmdlet. See more on github and the wiki pages.\n#>\nfunction Get-D365PackageLabelResources {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    param (\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true)]\n        [Parameter(Mandatory = $true, ParameterSetName = 'Specific')]\n        [Alias('Path')]\n        [string] $FilePath,\n\n        [string] $Name = \"*\",\n\n        [string] $Value = \"*\",\n\n        [switch] $IncludePath\n    )\n\n    BEGIN {}\n\n    PROCESS {\n        $assembly = [Reflection.Assembly]::LoadFile($FilePath)\n\n        $resNames = $assembly.GetManifestResourceNames()\n        $resname = $resNames[0].Replace(\".resources\", \"\")\n        $resLanguage = $resname.Split(\".\")[1]\n\n        $resMan = New-Object -TypeName System.Resources.ResourceManager -ArgumentList $resname, $assembly\n\n        $language = New-Object System.Globalization.CultureInfo -ArgumentList \"en-US\"\n        $resources = $resMan.GetResourceSet($language, $true, $true)\n\n        foreach ($obj in $resources) {\n            if ($obj.Name -NotLike $Name) { continue }\n            if ($obj.Value -NotLike $Value) { continue }\n            $res = [PSCustomObject]@{\n                Name     = $obj.Name\n                Language = $resLanguage\n                Value    = $obj.Value\n            }\n\n            if ($IncludePath.IsPresent) {\n                $res | Add-Member -MemberType NoteProperty -Name 'Path' -Value $FilePath\n            }\n\n            $res\n        }\n    }\n\n    END {}\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365productinformation.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Returns information about D365FO\n        \n    .DESCRIPTION\n        Gets detailed information about application and platform\n        \n    .EXAMPLE\n        PS C:\\> Get-D365ProductInformation\n        \n        This will get product, platform and application version details for the environment\n        \n    .NOTES\n        Tags: Build, Version, Reference, ProductVersion, ProductDetails, Product\n        \n        Author: Rasmus Andersen (@ITRasmus)\n        \n        The cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations.\n        The call to the dll file gets all relevant product details for the environment.\n        \n        \n#>\nfunction Get-D365ProductInformation {\n    [CmdletBinding()]\n    param ()\n    \n    return Get-ProductInfoProvider\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365rsatcertificatethumbprint.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the thumbprint from the RSAT certificate\n        \n    .DESCRIPTION\n        Locate the thumbprint for the certificate created during the RSAT installation\n        \n    .EXAMPLE\n        PS C:\\> Get-D365RsatCertificateThumbprint\n        \n        This will locate any certificates that has 127.0.0.1 in its name.\n        It will show the subject and the thumbprint values.\n        \n    .NOTES\n        Tags: RSAT, Certificate, Testing, Regression Suite Automation Test, Regression, Test, Automation.\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Get-D365RsatCertificateThumbprint {\n    [CmdletBinding()]\n    [OutputType()]\n    param ( )\n    \n    Get-ChildItem -Path Cert:\\LocalMachine\\My | Where-Object Subject -like \"*127.0.0.1*\" | Format-Table Thumbprint, Subject, FriendlyName, NotAfter\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365rsatplaybackfile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the RSAT playback files\n        \n    .DESCRIPTION\n        Get all the RSAT playback files from the last executions\n        \n    .PARAMETER Path\n        The path where the RSAT tool will be writing the files\n        \n        The default path is:\n        \"C:\\Users\\USERNAME\\AppData\\Roaming\\regressionTool\\playback\"\n        \n    .PARAMETER Name\n        Name of Test Case that you are looking for\n        \n        Default value is \"*\" which will search for all Test Cases and their corresponding files\n        \n    .PARAMETER ExecutionUsername\n        Name of the user account has been running the RSAT tests on a machine that isn't the same as the current user\n        \n        Will enable you to log on to RSAT server that is running the tests from a console, automated, and is other account than the current user\n        \n    .EXAMPLE\n        PS C:\\> Get-D365RsatPlaybackFile\n        \n        This will get all the RSAT playback files.\n        It will search for the files in the current user AppData system folder.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365RsatPlaybackFile -Name *4080*\n        \n        This will get all the RSAT playback files which has \"4080\" as part of its name.\n        It will search for the files in the current user AppData system folder.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365RsatPlaybackFile -ExecutionUsername RSAT-ServiceAccount\n        \n        This will get all the RSAT playback files that were executed by the RSAT-ServiceAccount user.\n        It will search for the files in the RSAT-ServiceAccount user AppData system folder.\n        \n    .NOTES\n        Tags: RSAT, Testing, Regression Suite Automation Test, Regression, Test, Automation, Playback\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Get-D365RsatPlaybackFile {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    [OutputType()]\n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = \"Default\")]\n        [string] $Path = $Script:RsatplaybackPath,\n        \n        [Parameter(Mandatory = $false)]\n        [string] $Name = \"*\",\n\n        [Parameter(Mandatory = $false, ParameterSetName = \"ExecutionUser\")]\n        [string] $ExecutionUsername\n    )\n    \n    if ($PSCmdlet.ParameterSetName -eq \"ExecutionUser\") {\n        $Path = $Path.Replace(\"$($env:UserName)\", $ExecutionUsername)\n\n        if (-not (Test-PathExists -Path $Path -Type Container)) { return }\n    }\n\n    Get-ChildItem -Path $Path -Recurse | Where-Object { $_.Name -like $Name } | Select-PSFObject \"LastWriteTime as LastRuntime\", \"Name as Filename\", \"Fullname as File\"\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365rsatsoaphostname.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the SOAP hostname for the D365FO environment\n        \n    .DESCRIPTION\n        Get the SOAP hostname from the IIS configuration, to be used during the Rsat configuration\n        \n    .EXAMPLE\n        PS C:\\> Get-D365RsatSoapHostname\n        \n        This will get the SOAP hostname from IIS.\n        It will display the SOAP URL / URI correctly formatted, to be used during the configuration of Rsat.\n        \n    .NOTES\n        Tags: RSAT, Testing, Regression Suite Automation Test, Regression, Test, Automation, SOAP\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Get-D365RsatSoapHostname {\n    [CmdletBinding()]\n    [OutputType()]\n    param ()\n\n    [PSCustomObject]@{\n        SoapHostname = (Get-WebBinding | Where-Object bindingInformation -like *soap*).bindingInformation.Replace(\"*:443:\", \"\")\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365runbook.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get a Dynamics 365 Runbook\n        \n    .DESCRIPTION\n        Get the full path and filename of a Dynamics 365 Runbook\n        \n    .PARAMETER Path\n        Path to the folder containing the runbook files\n        \n        The default path is \"InstallationRecord\" which is normally located on the \"C:\\DynamicsAX\\InstallationRecords\"\n        \n    .PARAMETER Name\n        Name of the runbook file that you are looking for\n        \n        The parameter accepts wildcards. E.g. -Name *hotfix-20181024*\n        \n    .PARAMETER Latest\n        Instruct the cmdlet to only get the latest runbook file, based on the last written attribute\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Runbook\n        \n        This will list all runbooks that are available in the default location.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Runbook -Latest\n        \n        This will get the latest runbook file from the default InstallationRecords directory on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer\n        \n        This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer | Out-File \"C:\\Temp\\d365fo.tools\\runbook-analyze-results.xml\"\n        \n        This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\n        The output will be saved into the \"C:\\Temp\\d365fo.tools\\runbook-analyze-results.xml\" file.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Runbook | Backup-D365Runbook\n        \n        This will save a copy of all runbooks from the default location and save them to \"c:\\temp\\d365fo.tools\\runbookbackups\"\n        \n    .EXAMPLE\n        PS C:\\> notepad.exe (Get-D365Runbook -Latest).File\n        \n        This will find the latest runbook file and open it with notepad.\n        \n    .NOTES\n        Tags: Runbook, Servicing, Hotfix, DeployablePackage, Deployable Package, InstallationRecordsDirectory, Installation Records Directory\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-D365Runbook {\n    [CmdletBinding()]\n    param (\n        [Parameter(ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]\n        [string] $Path = (Join-Path $Script:InstallationRecordsDir \"Runbooks\"),\n\n        [string] $Name = \"*\",\n\n        [switch] $Latest\n    )\n\n    begin {\n        if (-not (Test-PathExists -Path $Path -Type Container -WarningAction $WarningPreference -ErrorAction $ErrorActionPreference)) { return }\n    }\n    \n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n\n        $files = Get-ChildItem -Path \"$Path\\*.xml\" | Sort-Object -Descending { $_.LastWriteTime }\n\n        if ($Latest) {\n            $obj = $files | Select-Object -First 1\n\n            $obj | Select-PSFObject \"Name as Filename\", \"LastWriteTime as LastModified\", \"Fullname as File\"\n        }\n        else {\n            foreach ($obj in $files) {\n                if ($obj.Name -NotLike $Name) { continue }\n\n                $obj | Select-PSFObject \"Name as Filename\", \"LastWriteTime as LastModified\", \"Fullname as File\"\n            }\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365runbookid.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get runbook id\n        \n    .DESCRIPTION\n        Get the runbook id from inside a runbook file\n        \n    .PARAMETER Path\n        Path to the runbook file that you want to analyse\n        \n        Accepts value from pipeline, also by property\n        \n    .EXAMPLE\n        PS C:\\> Get-D365RunbookId -Path \"C:\\DynamicsAX\\InstallationRecords\\Runbooks\\Runbook.xml\"\n        \n        This will inspect the Runbook.xml file and output the runbookid from inside the XML document.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Runbook | Get-D365RunbookId\n        \n        This will find all runbook file(s) and have them analyzed by the Get-D365RunbookId cmdlet to output the runbookid(s).\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Runbook -Latest | Get-D365RunbookId\n        \n        This will find the latest runbook file and have it analyzed by the Get-D365RunbookId cmdlet to output the runbookid.\n        \n    .NOTES\n        Tags: Runbook, Analyze, RunbookId, Runbooks\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Get-D365RunbookId {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]\n        [Alias('File')]\n        [string] $Path\n    )\n\n    process {\n        if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n        [xml]$xmlRunbook = Get-Content $Path\n\n        [PSCustomObject]@{\n            RunbookId = $xmlRunbook.SelectSingleNode(\"/RunbookData/RunbookID\").\"#text\"\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365runbooklogfile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get log file from a Runbook step\n        \n    .DESCRIPTION\n        Get the log files for a specific Runbook step\n        \n    .PARAMETER Path\n        Path to Software Deployable Package that was run in connection with the runbook\n        \n    .PARAMETER Step\n        Step id for the step that you want to locate the log files for\n        \n    .PARAMETER Latest\n        Instruct the cmdlet to only work with the latest log file\n        \n        Is based on the last written attribute on the log file\n        \n    .PARAMETER OpenInEditor\n        Instruct the cmdlet to open the log file in the default text editor\n        \n    .EXAMPLE\n        PS C:\\> Get-D365RunbookLogFile -Path \"C:\\Temp\\PU35\" -Step 34\n        \n        This will locate all logfiles that has been outputted from the Step 34 from the PU35 installation.\n        The output will list the complete path to the log files.\n        \n        An output example:\n        \n        Filename     : AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log\n        LastModified : 8/7/2020 12:40:34 PM\n        File         : C:\\Temp\\PU35\\RunbookWorkingFolder\\Runbook\\MININT-F36S5EH\\DIXFService\\34\\Log\\AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log\n        \n        Filename     : AutoUpdateDIXFService.ps1-2020-07-8--12-36-22.log\n        LastModified : 8/7/2020 12:36:22 PM\n        File         : C:\\Temp\\PU35\\RunbookWorkingFolder\\Runbook\\MININT-F36S5EH\\DIXFService\\34\\Log\\AutoUpdateDIXFService.ps1-2020-07-8--12-36-22.log\n        \n        Filename     : AutoUpdateDIXFService.ps1-2020-05-8--19-15-07.log\n        LastModified : 8/5/2020 7:15:07 PM\n        File         : C:\\Temp\\PU35\\RunbookWorkingFolder\\Runbook\\MININT-F36S5EH\\DIXFService\\34\\Log\\AutoUpdateDIXFService.ps1-2020-05-8--19-15-07.log\n        \n    .EXAMPLE\n        PS C:\\> Get-D365RunbookLogFile -Path \"C:\\Temp\\PU35\" -Step 34 -Latest\n        \n        This will locate all logfiles that has been outputted from the Step 34 from the PU35 installation.\n        The output will be limited to the latest log, based on last write time.\n        The output will list the complete path to the log file.\n        \n        An output example:\n        \n        Filename     : AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log\n        LastModified : 8/7/2020 12:40:34 PM\n        File         : C:\\Temp\\PU35\\RunbookWorkingFolder\\Runbook\\MININT-F36S5EH\\DIXFService\\34\\Log\\AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log\n        \n    .EXAMPLE\n        PS C:\\> Get-D365RunbookLogFile -Path \"C:\\Temp\\PU35\" -Step 34 -OpenInEditor\n        \n        This will locate all logfiles that has been outputted from the Step 34 from the PU35 installation.\n        The Get-D365RunbookLogFile will open all log files in the default text editor.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365RunbookLogFile -Path \"C:\\Temp\\PU35\" -Step 34 -Latest -OpenInEditor\n        \n        This will locate all logfiles that has been outputted from the Step 34 from the PU35 installation.\n        The output will be limited to the latest log, based on last write time.\n        The Get-D365RunbookLogFile will open the log file in the default text editor.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnlyAsObjects | Get-D365RunbookLogFile -Path \"C:\\Temp\\PU35\" -OpenInEditor\n        \n        This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\n        The output from Invoke-D365RunbookAnalyzer will only contain failed steps.\n        The Get-D365RunbookLogFile will open all log files for the failed step.\n        \n    .NOTES\n        Tags: Runbook, Servicing, Hotfix, DeployablePackage, Deployable Package, InstallationRecordsDirectory, Installation Records Directory\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-D365RunbookLogFile {\n    [CmdletBinding()]\n    [OutputType('System.String')]\n    param (\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]\n        [Alias('File')]\n        [string] $Path,\n\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]\n        [Alias('StepId')]\n        [string] $Step,\n\n        [switch] $Latest,\n\n        [switch] $OpenInEditor\n\n    )\n    \n    process {\n        if (-not (Test-PathExists -Path $Path -Type Container)) { return }\n\n        $stepPath = Get-ChildItem -Path $Path -Filter $step -Recurse -Directory | Select-Object -First 1\n\n        if ($null -eq $stepPath) {\n            $messageString = \"Couldn't locate a folder with the specified step id.\"\n            Write-PSFMessage -Level Host -Message $messageString\n            Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', '')))\n        }\n\n        $files = @(Get-ChildItem -Path \"$($stepPath.FullName)\\Log\\*.log\" -Recurse | Sort-Object -Descending { $_.LastWriteTime })\n\n        if ($files.Count -lt 1) {\n            $messageString = \"Couldn't locate any log files in the folder associated with the step.\"\n            Write-PSFMessage -Level Host -Message $messageString\n            Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', '')))\n        }\n\n        if ($Latest) {\n            $files = $files | Select-Object -First 1\n        }\n        \n        foreach ($obj in $files) {\n            $obj | Select-PSFObject \"Name as Filename\", \"LastWriteTime as LastModified\", \"Fullname as File\" -TypeName \"D365FO.TOOLS.FileObject\"\n        }\n\n        if($OpenInEditor) {\n            foreach ($obj in $files) {\n                & \"$($obj.Fullname)\"\n            }\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365sdpcleanup.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the cleanup retention period\n        \n    .DESCRIPTION\n        Gets the configured retention period before updates are deleted\n        \n    .EXAMPLE\n        PS C:\\> Get-D365SDPCleanUp\n        \n        This will get the configured retention period from the registry\n        \n    .NOTES\n        Tags: CleanUp, Retention, Servicing, Cut Off, DeployablePackage, Deployable Package\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        This cmdlet is based on the findings from Alex Kwitny (@AlexOnDAX)\n        \n        See his blog for more info:\n        http://www.alexondax.com/2018/04/msdyn365fo-how-to-adjust-your.html\n        \n#>\nfunction Get-D365SDPCleanUp {\n    [CmdletBinding()]\n    param (\n        \n    )\n    \n    $RegSplat = @{\n        Path = \"HKLM:\\SOFTWARE\\Microsoft\\Dynamics\\Deployment\\\"\n        Name = \"CutoffDaysForCleanup\"\n    }\n    \n    [PSCustomObject] @{\n        CutoffDaysForCleanup = $( if (Test-RegistryValue @RegSplat) {Get-ItemPropertyValue @RegSplat} else {\"\"} )\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365sdpdetails.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get details from the Software Deployable Package\n        \n    .DESCRIPTION\n        Details details about the inner modules / packages that a Software Deployable Contains\n        \n    .PARAMETER Path\n        Path to the Software Deployable Package that you want to work against\n        \n        The cmdlet supports a path to a zip-file or directory with the unpacked content\n        \n    .EXAMPLE\n        PS C:\\> Get-D365SDPDetails -Path 'C:\\Temp\\RV-10.0.36.44.zip'\n        \n        This will display the basic details about the package.\n        The package is a zip file.\n        \n        A result set example:\n        \n        Platform PlatformVersion Modules\n        -------- --------------- -------\n        Update55 7.0.6651.92     {@{Name=RapidValue; Version=7.0.6651.92}, @{Name=TCLCommon; Version=7.0.6651.92}, @{Name=TC...\n        \n    .EXAMPLE\n        PS C:\\> Get-D365SDPDetails -Path 'C:\\Temp\\RV-10.0.36.44'\n        \n        This will display the basic details about the package.\n        The package is extracted to a local folder.\n        \n        A result set example:\n        \n        Platform PlatformVersion Modules\n        -------- --------------- -------\n        Update55 7.0.6651.92     {@{Name=RapidValue; Version=7.0.6651.92}, @{Name=TCLCommon; Version=7.0.6651.92}, @{Name=TC...\n        \n    .EXAMPLE\n        PS C:\\> Get-D365SDPDetails -Path 'C:\\Temp\\RV-10.0.36.44.zip' | Select-Object -ExpandProperty Modules\n        \n        This will display the module details that are part of the package.\n        The package is a zip file.\n        \n        A result set example:\n        \n        Name       Version\n        ----       -------\n        RapidValue 7.0.6651.92\n        TCLCommon  7.0.6651.92\n        TCLLabel   7.0.6651.92\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>#\nfunction Get-D365SDPDetails {\n    [CmdletBinding()]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    param (\n        [Parameter(Mandatory = $True)]\n        [Alias('File')]\n        [string] $Path\n    )\n\n    $pathWorkDirectory = \"$([System.IO.Path]::GetTempPath())d365fo.tools\\$([System.Guid]::NewGuid().Guid)\"\n    #Make sure the work path is created and available\n    New-Item -Path $pathWorkDirectory -ItemType Directory -Force -ErrorAction Ignore > $null\n    $pathHotfix = Join-Path -Path $pathWorkDirectory -ChildPath \"HotfixInstallationInfo.xml\"\n\n    Invoke-TimeSignal -Start\n\n    if ($Path.EndsWith(\".zip\")) {\n        <#\n            If we have a zip file, we'll extract the files, to mimic a folder\n            Will copy to the default Windows temporary folder\n        #>\n\n        Unblock-File -Path $Path\n\n        $file = [System.IO.File]::Open($Path, [System.IO.FileMode]::Open)\n        $zipArch = [System.IO.Compression.ZipArchive]::new($file)\n        $zipEntry = $zipArch.GetEntry(\"HotfixInstallationInfo.xml\")\n\n        if (-not $zipEntry) {\n            $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.\"\n            Write-PSFMessage -Level Host -Message $messageString\n            Stop-PSFFunction -Message \"Stopping because HotfixInstallationInfo.xml wasn't found.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', '')))\n        }\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        [System.IO.Compression.ZipFileExtensions]::ExtractToFile($zipEntry, $pathHotfix, $true)\n\n\n        foreach ($nuget in $($zipArch.Entries | Where-Object Fullname -like \"AOSService[\\/]Packages[\\/]*.nupkg\")) {\n            $pathNuget = \"$pathWorkDirectory\\$($nuget.name).zip\"\n            \n            # The nuget file contains module name in correct casing\n            [System.IO.Compression.ZipFileExtensions]::ExtractToFile($nuget, $pathNuget, $true)\n\n        }\n\n        # Clear out any zip archive objects from memory\n        if ($zipArch) {\n            $zipArch.Dispose()\n        }\n\n        if ($file) {\n            $file.Close()\n            $file.Dispose()\n        }\n    }\n    else {\n        <#\n            Will copy to the default Windows temporary folder\n        #>\n        Copy-Item -Path \"$Path\\HotfixInstallationInfo.xml\" -Destination $pathHotfix -Force\n\n        foreach ($nuget in $(Get-ChildItem -Path \"$Path\\AOSService\\Packages\\*.nupkg\")) {\n            Copy-Item -Path $nuget.FullName -Destination \"$pathWorkDirectory\\$($nuget.Name).zip\" -Force\n        }\n    }\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    [System.Collections.Generic.List[System.Object]] $modules = @()\n\n    foreach ($nuget in $(Get-ChildItem -Path \"$pathWorkDirectory\\*.nupkg.zip\")) {\n        <#\n            nuget contains a nuspec file\n            nuspec is a XML containing the details we are looking for\n        #>\n        $pathXml = $nuget.FullName + \".nuspec\"\n\n        $fileNuget = [System.IO.File]::Open($nuget.FullName, [System.IO.FileMode]::Open)\n        $zipNuget = [System.IO.Compression.ZipArchive]::new($fileNuget)\n        $zipNugetEntry = $zipNuget.Entries | Where-Object Name -like \"*.nuspec\" | Select-Object -First 1\n        [System.IO.Compression.ZipFileExtensions]::ExtractToFile($zipNugetEntry, $pathXml, $true)\n\n        [xml] $moduleSpec = Get-Content -Path $pathXml -Raw\n\n        $modules.Add(\n            [PSCustomObject]@{\n                Name    = $moduleSpec.package.metadata.summary\n                Version = $moduleSpec.package.metadata.version\n            }\n        )\n\n        # Clear out any inner zip archive objects from memory\n        if ($zipNuget) {\n            $zipNuget.Dispose()\n        }\n        \n        if ($fileNuget) {\n            $fileNuget.Close()\n            $fileNuget.Dispose()\n        }\n    }\n\n    [xml] $hotfix = Get-Content -Path \"$pathWorkDirectory\\HotfixInstallationInfo.xml\" -Raw\n\n    [PSCustomObject]@{\n        Platform        = $hotfix.HotfixInstallationInfo.PlatformReleaseDisplayName\n        PlatformVersion = $hotfix.HotfixInstallationInfo.PlatformVersion\n        Modules         = $modules\n    }\n    \n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365table.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get a table\n        \n    .DESCRIPTION\n        Get a table either by TableName (wildcard search allowed) or by TableId\n        \n    .PARAMETER Name\n        Name of the table that you are looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"Cust*\"\n        \n        Default value is \"*\" which will search for all tables\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER Id\n        The specific id for the table you are looking for\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Table -Name CustTable\n        \n        Will get the details for the CustTable\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Table -Id 10347\n        \n        Will get the details for the table with the id 10347.\n        \n    .NOTES\n        Tags: Table, Tables, AOT, TableId, Development\n        \n        Author: Mötz Jensen (@splaxi)\n        \n        The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages.\n        \n#>\nfunction Get-D365Table {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )]\n        [string[]] $Name = \"*\",\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'TableId', Position = 1 )]\n        [int] $Id,\n\n        [Parameter(Mandatory = $false, Position = 2 )]\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Mandatory = $false, Position = 3 )]\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false, Position = 4 )]\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false, Position = 5 )]\n        [string] $SqlPwd = $Script:DatabaseUserPassword\n    )\n\n    BEGIN {}\n\n    PROCESS {\n\n        $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n        $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n            SqlUser = $SqlUser; SqlPwd = $SqlPwd\n        }\n\n        $sqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n\n        $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\get-tables.sql\") -join [Environment]::NewLine\n\n        $dataTable = New-Object system.Data.DataSet\n        $dataAdapter = New-Object system.Data.SqlClient.SqlDataAdapter($sqlCommand)\n        $dataAdapter.fill($dataTable) | Out-Null\n\n        foreach ($localName in $Name) {\n            if ($PSCmdlet.ParameterSetName -eq \"Default\") {\n                foreach ($obj in $dataTable.Tables.Rows) {\n                    if ($obj.AotName -NotLike $localName) { continue }\n                    [PSCustomObject]@{\n                        TableId   = $obj.TableId\n                        TableName = $obj.AotName\n                        SqlName   = $obj.SqlName\n                    }\n                }\n            }\n            else {\n                $obj = $dataTable.Tables.Rows | Where-Object TableId -eq $Id | Select-Object -First 1\n                [PSCustomObject]@{\n                    TableId   = $obj.TableId\n                    TableName = $obj.AotName\n                    SqlName   = $obj.SqlName\n                }\n            }\n        }\n    }\n\n    END {}\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365tablefield.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get a field from table\n        \n    .DESCRIPTION\n        Get a field either by FieldName (wildcard search allowed) or by FieldId\n        \n    .PARAMETER TableId\n        The id of the table that the field belongs to\n        \n    .PARAMETER Name\n        Name of the field that you are looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"Account*\"\n        \n        Default value is \"*\" which will search for all fields\n        \n    .PARAMETER FieldId\n        Id of the field that you are looking for\n        \n        Type is integer\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER TableName\n        Name of the table that the field belongs to\n        \n        Search will only return the first hit (unordered) and work against that hit\n        \n    .PARAMETER IncludeTableDetails\n        Switch options to enable the result set to include extended details\n        \n    .PARAMETER SearchAcrossTables\n        Switch options to force the cmdlet to search across all tables when looking for the field\n        \n    .EXAMPLE\n        PS C:\\> Get-D365TableField -TableId 10347\n        \n        Will get all field details for the table with id 10347.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365TableField -TableName CustTable\n        \n        Will get all field details for the CustTable table.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365TableField -TableId 10347 -FieldId 175\n        \n        Will get the details for the field with id 175 that belongs to the table with id 10347.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365TableField -TableId 10347 -Name \"VATNUM\"\n        \n        Will get the details for the \"VATNUM\" that belongs to the table with id 10347.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365TableField -TableId 10347 -Name \"VAT*\"\n        \n        Will get the details for all fields that fits the search \"VAT*\" that belongs to the table with id 10347.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365TableField -Name AccountNum -SearchAcrossTables\n        \n        Will search for the AccountNum field across all tables.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365TableField -TableName CustTable -IncludeTableDetails\n        \n        Will get all field details for the CustTable table.\n        Will include table details in the output.\n        \n    .NOTES\n        Tags: Table, Tables, Fields, TableField, Table Field, TableName, TableId\n        \n        Author: Mötz Jensen (@splaxi)\n        \n        The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages.\n        \n        \n#>\nfunction Get-D365TableField {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 1 )]\n        [int] $TableId,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'TableName', Position = 2 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'SearchByNameForce', Position = 1 )]\n        [string] $Name = \"*\",\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 3 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'TableName', ValueFromPipelineByPropertyName = $true, Position = 3 )]\n        [int] $FieldId,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 4 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'TableName', Position = 4 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'SearchByNameForce', Position = 3 )]\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 5 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'TableName', Position = 5 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'SearchByNameForce', Position = 4 )]\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 6 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'TableName', Position = 6 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'SearchByNameForce', Position = 5 )]\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 7 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'TableName', Position = 7 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'SearchByNameForce', Position = 6 )]\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'TableName', Position = 1 )]\n        [string] $TableName,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default')]\n        [Parameter(Mandatory = $false, ParameterSetName = 'TableName')]\n        [switch] $IncludeTableDetails,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'SearchByNameForce', Position = 2 )]\n        [switch] $SearchAcrossTables\n    )\n    BEGIN {\n        $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n        $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n            SqlUser = $SqlUser; SqlPwd = $SqlPwd\n        }\n\n        $sqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n\n    }\n    \n    PROCESS {\n        if ($PSCmdlet.ParameterSetName -eq \"TableName\") {\n            $TableId = (Get-D365Table -Name $TableName | Select-Object -First 1).TableId\n        }\n\n        if ($SearchAcrossTables) {\n            $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\get-alltablefields.sql\") -join [Environment]::NewLine\n        }\n        else {\n            $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\get-tablefields.sql\") -join [Environment]::NewLine\n            $null = $sqlCommand.Parameters.Add(\"@TableId\", $TableId)\n        }\n\n        $dataTable = New-Object system.Data.DataSet\n        $dataAdapter = New-Object system.Data.SqlClient.SqlDataAdapter($sqlCommand)\n        $dataAdapter.fill($dataTable) | Out-Null\n\n        foreach ($obj in $dataTable.Tables.Rows) {\n            if ($obj.FieldId -eq 0) {\n                $TableName = $obj.AotName\n\n                continue\n            }\n\n            if ($PSBoundParameters.ContainsKey(\"FieldId\")) {\n                if ($obj.FieldId -NotLike $FieldId) { continue }\n            }\n            else {\n                if ($obj.AotName -NotLike $Name) { continue }\n            }\n            $res = [PSCustomObject]@{\n                FieldId   = $obj.FieldId\n                FieldName = $obj.AotName\n                SqlName   = $obj.SqlName\n            }\n\n            if ($IncludeTableDetails) {\n                $res | Add-Member -MemberType NoteProperty -Name 'TableId' -Value $obj.TableId\n                $res | Add-Member -MemberType NoteProperty -Name 'TableName' -Value $TableName\n            }\n            if ($SearchAcrossTables) {\n                $res | Add-Member -MemberType NoteProperty -Name 'TableId' -Value $obj.TableId\n            }\n\n            $res\n        }\n    }\n\n    END {}\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365tablesequence.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the sequence object for table\n        \n    .DESCRIPTION\n        Get the sequence details for tables\n        \n    .PARAMETER TableName\n        Name of the table that you want to work against\n        \n        Accepts wildcards for searching. E.g. -TableName \"Cust*\"\n        \n        Default value is \"*\" which will search for all tables\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .EXAMPLE\n        PS C:\\> Get-D365TableSequence | Format-Table\n        \n        This will get all the sequence details for all tables inside the database.\n        It will format the output as a table for better overview.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365TableSequence -TableName \"Custtable\" | Format-Table\n        \n        This will get the sequence details for the CustTable in the database.\n        It will format the output as a table for better overview.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365TableSequence -TableName \"Cust*\" | Format-Table\n        \n        This will get the sequence details for all tables that matches the search \"Cust*\" in the database.\n        It will format the output as a table for better overview.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Table -Name CustTable | Get-D365TableSequence | Format-Table\n        \n        This will get the table details from the Get-D365Table cmdlet and pipe that into Get-D365TableSequence.\n        This will get the sequence details for the CustTable in the database.\n        It will format the output as a table for better overview.\n        \n    .NOTES\n        Tags: Table, RecId, Sequence, Record Id\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-D365TableSequence {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 1 )]\n        [Alias('Name')]\n        [string] $TableName = \"*\",\n\n        [Parameter(Mandatory = $false, Position = 2 )]\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Mandatory = $false, Position = 3 )]\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false, Position = 4 )]\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false, Position = 5 )]\n        [string] $SqlPwd = $Script:DatabaseUserPassword\n    )\n    BEGIN {}\n    \n    PROCESS {\n        $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n        $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n            SqlUser = $SqlUser; SqlPwd = $SqlPwd\n        }\n\n        $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n        $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\get-tablesequence.sql\") -join [Environment]::NewLine\n        $null = $sqlCommand.Parameters.AddWithValue('@TableName', $TableName.Replace(\"*\", \"%\"))\n        \n        $datatable = New-Object system.Data.DataSet\n        $dataadapter = New-Object system.Data.SqlClient.SqlDataAdapter($sqlcommand)\n        $dataadapter.fill($datatable) | Out-Null\n\n        foreach ($obj in $datatable.Tables.Rows) {\n            $res = [PSCustomObject]@{\n                SequenceName   = $obj.sequence_name\n                TableName = $obj.table_name\n                StartValue   = $obj.start_value\n                Increment = $obj.increment\n                MinimumValue = $obj.minimum_value\n                MaximumValue = $obj.maximum_value\n                IsCached = $obj.is_cached\n                CacheSize = $obj.cache_size\n                CurrentValue = $obj.current_value\n            }\n\n            $res\n        }\n    }\n\n    END {}\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365tablesinchangedtracking.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get table that is taking part of Change Tracking\n        \n    .DESCRIPTION\n        Get table(s) that is taking part of the SQL Server Change Tracking mechanism\n        \n    .PARAMETER Name\n        Name of the table that you are looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"Cust*\"\n        \n        Default value is \"*\" which will search for all tables\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .EXAMPLE\n        PS C:\\> Get-D365TablesInChangedTracking\n        \n        This will list all tables that are taking part in the SQL Server Change Tracking.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365TablesInChangedTracking -Name CustTable\n        \n        This will search for a table in the list of tables that are taking part in the SQL Server Change Tracking.\n        It will use the CustTable as the search pattern while searching for the table.\n        \n    .NOTES\n        Tags: Table, Change Tracking, Tablename, DMF, DIXF\n        \n        Author: Mötz Jensen (@splaxi)\n        \n#>\nfunction Get-D365TablesInChangedTracking {\n    [CmdletBinding()]\n    param (\n        [string] $Name = \"*\",\n\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword\n    )\n\n    PROCESS {\n\n        $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n        $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n            SqlUser = $SqlUser; SqlPwd = $SqlPwd\n        }\n\n        $sqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n\n        $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\get-tablesinchangedtracking.sql\") -join [Environment]::NewLine\n        $commandText = $commandText.Replace('@DATABASENAME', $DatabaseName)\n\n        $sqlCommand.CommandText = $commandText\n\n        $dataTable = New-Object system.Data.DataSet\n        $dataAdapter = New-Object system.Data.SqlClient.SqlDataAdapter($sqlCommand)\n        $dataAdapter.fill($dataTable) | Out-Null\n\n        foreach ($obj in $dataTable.Tables.Rows) {\n            if ($obj.name -NotLike $Name) { continue }\n\n            [PSCustomObject]@{\n                TableName = $obj.name\n            }\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365tfsuri.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the TFS / VSTS registered URL / URI\n        \n    .DESCRIPTION\n        Gets the URI from the configuration of the local tfs connection in visual studio\n        \n    .PARAMETER Path\n        Path to the tf.exe file that the cmdlet will invoke\n        \n    .EXAMPLE\n        PS C:\\> Get-D365TfsUri\n        \n        This will invoke the default tf.exe client located in the Visual Studio 2015 directory\n        and fetch the configured URI.\n        \n    .NOTES\n        Tags: TFS, VSTS, URL, URI, Servicing, Development\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Get-D365TfsUri {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )]\n        [string]$Path = $Script:TfDir\n    )\n    \n    $executable = Join-Path $Path \"tf.exe\"\n    if (!(Test-PathExists -Path $executable -Type Leaf)) {return}\n\n    Write-PSFMessage -Level Verbose -Message \"Invoking tf.exe\"\n    #* Small hack to get the output from the execution into a variable.\n    $res = & $executable \"settings\" \"connections\" 2>$null\n    Write-PSFMessage -Level Verbose -Message \"Result from tf.exe: $res\" -Target $res\n\n    if (![string]::IsNullOrEmpty($res)) {\n        [PSCustomObject]@{\n            TfsUri = $res[2].Split(\" \")[0]\n        }\n    }\n    else {\n        Write-PSFMessage -Level Host -Message \"No TFS / VSTS connections found. It looks like you haven't configured the server connection and workspace yet.\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365tfsworkspace.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the TFS / VSTS registered workspace path\n        \n    .DESCRIPTION\n        Gets the workspace path from the configuration of the local tfs in visual studio\n        \n    .PARAMETER Path\n        Path to the directory where the Team Foundation Client executable is located\n        \n    .PARAMETER TfsUri\n        Uri to the TFS / VSTS that the workspace is connected to\n        \n    .EXAMPLE\n        PS C:\\> Get-D365TfsWorkspace -TfsUri https://PROJECT.visualstudio.com\n        \n        This will invoke the default tf.exe client located in the Visual Studio 2015 directory\n        and fetch the configured URI.\n        \n    .NOTES\n        Tags: TFS, VSTS, URL, URI, Servicing, Development\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Get-D365TfsWorkspace {\n    [CmdletBinding()]\n    param (\n        [string] $Path = $Script:TfDir,\n\n        [Parameter(ValueFromPipelineByPropertyName = $true)]\n        [string] $TfsUri = $Script:TfsUri\n    )\n    \n    process {\n        $executable = Join-Path $Path \"tf.exe\"\n        if (!(Test-PathExists -Path $executable -Type Leaf)) { return }\n\n        if ([system.string]::IsNullOrEmpty($TfsUri)) {\n            Write-PSFMessage -Level Host -Message \"The supplied uri <c='em'>was empty</c>. Please update the active d365 environment configuration or simply supply the -TfsUri to the cmdlet.\"\n            Stop-PSFFunction -Message \"Stopping because TFS URI is missing.\"\n            return\n        }\n\n        Write-PSFMessage -Level Verbose -Message \"Invoking tf.exe\"\n        #* Small hack to get the output from the execution into a variable.\n        $res = & $executable \"vc\" \"workspaces\" \"/collection:$TfsUri\" \"/format:detailed\" 2>$null\n\n        if (![string]::IsNullOrEmpty($res)) {\n            [PSCustomObject]@{\n                TfsWorkspacePath = ($res | select-string \"meta\").ToString().Trim().Split(\" \")[1]\n            }\n        }\n        else {\n            Write-PSFMessage -Level Host -Message \"No matching workspace configuration found for the specified URI. Either the URI is wrong or you haven't configured the server connection / workspace details correctly.\"\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365url.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the url for accessing the instance\n        \n    .DESCRIPTION\n        Get the complete URL for accessing the Dynamics 365 Finance & Operations instance running on this machine\n        \n    .PARAMETER Force\n        Switch to instruct the cmdlet to retrieve the name from the system files\n        instead of the name stored in memory after loading this module.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Url\n        \n        This will get the correct URL to access the environment\n        \n    .NOTES\n        Tags: URL, URI, Servicing\n        \n        Author: Rasmus Andersen (@ITRasmus)\n        \n        The cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations.\n        The call to the dll file gets all registered URL for the environment.\n        \n#>\nfunction Get-D365Url {\n    [CmdletBinding()]\n    param (\n        [switch] $Force\n    )\n    \n    if ($Force) {\n        $Url = \"https://$($(Get-D365EnvironmentSettings).Infrastructure.FullyQualifiedDomainName)\"\n    }\n    else {\n        $Url = $Script:Url\n        \n    }\n    [PSCustomObject]@{\n        Url = $Url\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365user.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get users from the environment\n        \n    .DESCRIPTION\n        Get all relevant user details from the Dynamics 365 for Finance & Operations\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER Email\n        The search string to select which user(s) should be updated\n        \n        The parameter supports wildcards. E.g. -Email \"*@contoso.com*\"\n        \n        Default value is \"*\" to get all users\n        \n    .PARAMETER ExcludeSystemUsers\n        Instructs the cmdlet to filter out all known system users\n        \n    .EXAMPLE\n        PS C:\\> Get-D365User\n        \n        This will get all users from the environment.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365User -ExcludeSystemUsers\n        \n        This will get all users from the environment, but filter out all known system user accounts.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365User -Email \"*contoso.com\"\n        \n        This will search for all users with an e-mail address containing 'contoso.com' from the environment.\n        \n    .NOTES\n        Tags: User, Users\n        \n        Author: Mötz Jensen (@Splaxi)\n        Author: Rasmus Andersen (@ITRasmus)\n#>\nfunction Get-D365User {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $false, Position = 1)]\n        [string]$DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Mandatory = $false, Position = 2)]\n        [string]$DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false, Position = 3)]\n        [string]$SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false, Position = 4)]\n        [string]$SqlPwd = $Script:DatabaseUserPassword,\n\n        [Parameter(Mandatory = $false, Position = 5)]\n        [string]$Email = \"*\",\n\n        [switch]$ExcludeSystemUsers\n\n    )\n\n    $exclude = @(\"DAXMDSRunner.com\", \"dynamics.com\")\n\n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n    $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd\n    }\n\n    $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n\n    $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\get-user.sql\") -join [Environment]::NewLine\n\n    $null = $sqlCommand.Parameters.Add(\"@Email\", $Email.Replace(\"*\", \"%\"))\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n    \n        $reader = $sqlCommand.ExecuteReader()\n\n        while ($reader.Read() -eq $true) {\n            $res = [PSCustomObject]@{\n                UserId           = \"$($reader.GetString($($reader.GetOrdinal(\"ID\"))))\"\n                Name             = \"$($reader.GetString($($reader.GetOrdinal(\"NAME\"))))\"\n                NetworkAlias     = \"$($reader.GetString($($reader.GetOrdinal(\"NETWORKALIAS\"))))\"\n                NetworkDomain    = \"$($reader.GetString($($reader.GetOrdinal(\"NETWORKDOMAIN\"))))\"\n                Sid              = \"$($reader.GetString($($reader.GetOrdinal(\"SID\"))))\"\n                IdentityProvider = \"$($reader.GetString($($reader.GetOrdinal(\"IDENTITYPROVIDER\"))))\"\n                Enabled          = [bool][int]\"$($reader.GetInt32($($reader.GetOrdinal(\"ENABLE\"))))\"\n                Email            = \"$($reader.GetString($($reader.GetOrdinal(\"NETWORKALIAS\"))))\"\n                Company          = \"$($reader.GetString($($reader.GetOrdinal(\"COMPANY\"))))\"\n            }\n\n            if ($ExcludeSystemUsers) {\n                $temp = $res.Email.Split(\"@\")[1]\n                if ($exclude -contains $temp) {\n                    continue\n                }\n                elseif ($res.UserId -eq 'Guest') {\n                    continue\n                }\n            }\n\n            $res\n        }\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n    finally {\n        $reader.close()\n\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365userauthenticationdetail.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Cmdlet used to get authentication details about a user\n        \n    .DESCRIPTION\n        The cmdlet will take the e-mail parameter and use it to lookup all the needed details for configuring authentication against Dynamics 365 Finance & Operations\n        \n    .PARAMETER Email\n        The e-mail address / login name of the user that the cmdlet must gather details about\n        \n    .EXAMPLE\n        PS C:\\> Get-D365UserAuthenticationDetail -Email \"Claire@contoso.com\"\n        \n        This will get all the authentication details for the user account with the email address \"Claire@contoso.com\"\n        \n    .NOTES\n        Tags: User, Users, Security, Configuration, Authentication\n        \n        Author : Rasmus Andersen (@ITRasmus)\n        Author : Mötz Jensen (@splaxi)\n        \n#>\nfunction Get-D365UserAuthenticationDetail {\n    param(\n        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]\n        [string] $Email\n    )\n\n    process {\n        $instanceProvider = Get-InstanceIdentityProvider\n\n        [string]$identityProvider = Get-CanonicalIdentityProvider\n    \n        $networkDomain = Get-NetworkDomain $Email\n\n        $instanceProviderName = $instanceProvider.TrimEnd('/')\n        $instanceProviderName = $instanceProviderName.Substring($instanceProviderName.LastIndexOf('/') + 1)\n        $instanceProviderIdentityProvider = Get-IdentityProvider \"sample@$instanceProviderName\"\n        $emailIdentityProvider = Get-IdentityProvider $Email\n\n        if ($instanceProviderIdentityProvider -ne $emailIdentityProvider) {\n            $identityProvider = $emailIdentityProvider\n        }\n\n        $SID = Get-UserSIDFromAad $Email $identityProvider\n\n        @{\"SID\"                = $SID\n            \"NetworkDomain\"    = $networkDomain\n            \"IdentityProvider\" = $identityProvider\n            \"InstanceProvider\" = $instanceProvider\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365visualstudiocompilerresult.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the compiler outputs presented\n        \n    .DESCRIPTION\n        Get the Visual Studio compiler outputs presented in a structured manner on the screen\n        \n    .PARAMETER Module\n        Name of the module that you want to work against\n        \n        Default value is \"*\" which will search for all modules\n        \n    .PARAMETER ErrorsOnly\n        Instructs the cmdlet to only output compile results where there was errors detected\n        \n    .PARAMETER OutputTotals\n        Instructs the cmdlet to output the total errors and warnings after the analysis\n        \n    .PARAMETER OutputAsObjects\n        Instructs the cmdlet to output the objects instead of formatting them\n        \n        If you don't assign the output, it will be formatted the same way as the original output, but without the coloring of the column values\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Default path is the same as the AOS service \"PackagesLocalDirectory\" directory\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Get-D365VisualStudioCompilerResult\n        \n        This will return the compiler output for all modules.\n        \n        A result set example:\n        \n        File                                                                                     Warnings Errors\n        ----                                                                                     -------- ------\n        K:\\AosService\\PackagesLocalDirectory\\ApplicationCommon\\BuildModelResult.log                    55      0\n        K:\\AosService\\PackagesLocalDirectory\\ApplicationFoundation\\BuildModelResult.log               692      0\n        K:\\AosService\\PackagesLocalDirectory\\ApplicationPlatform\\BuildModelResult.log                 155      0\n        K:\\AosService\\PackagesLocalDirectory\\ApplicationSuite\\BuildModelResult.log                  10916      0\n        K:\\AosService\\PackagesLocalDirectory\\CustomModule\\BuildModelResult.log                          1      2\n        \n    .EXAMPLE\n        PS C:\\> Get-D365VisualStudioCompilerResult -ErrorsOnly\n        \n        This will return the compiler output for all modules where there was errors in.\n        \n        A result set example:\n        \n        File                                                                                     Warnings Errors\n        ----                                                                                     -------- ------\n        K:\\AosService\\PackagesLocalDirectory\\CustomModule\\BuildModelResult.log                          1      2\n        \n    .EXAMPLE\n        PS C:\\> Get-D365VisualStudioCompilerResult -ErrorsOnly -OutputAsObjects\n        \n        This will return the compiler output for all modules where there was errors in.\n        The output will be PSObjects, which can be assigned to a variable and used for futher analysis.\n        \n        A result set example:\n        \n        File                                                                                     Warnings Errors\n        ----                                                                                     -------- ------\n        K:\\AosService\\PackagesLocalDirectory\\CustomModule\\BuildModelResult.log                          1      2\n        \n    .EXAMPLE\n        PS C:\\> Get-D365VisualStudioCompilerResult -OutputTotals\n        \n        This will return the compiler output for all modules and write a total overview to the console.\n        \n        A result set example:\n        \n        File                                                                                     Warnings Errors\n        ----                                                                                     -------- ------\n        K:\\AosService\\PackagesLocalDirectory\\ApplicationCommon\\BuildModelResult.log                    55      0\n        K:\\AosService\\PackagesLocalDirectory\\ApplicationFoundation\\BuildModelResult.log               692      0\n        K:\\AosService\\PackagesLocalDirectory\\ApplicationPlatform\\BuildModelResult.log                 155      0\n        K:\\AosService\\PackagesLocalDirectory\\ApplicationSuite\\BuildModelResult.log                  10916      0\n        K:\\AosService\\PackagesLocalDirectory\\CustomModule\\BuildModelResult.log                          1      2\n        \n        \n        Total Errors: 2\n        Total Warnings: 11819\n        \n    .NOTES\n        Tags: Compiler, Build, Errors, Warnings, Tasks\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        This cmdlet is inspired by the work of \"Vilmos Kintera\" (twitter: @DAXRunBase)\n        \n        All credits goes to him for showing how to extract these information\n        \n        His blog can be found here:\n        https://www.daxrunbase.com/blog/\n        \n        The specific blog post that we based this cmdlet on can be found here:\n        https://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/\n        \n        The github repository containing the original scrips can be found here:\n        https://github.com/DAXRunBase/PowerShell-and-Azure\n#>\nfunction Get-D365VisualStudioCompilerResult {\n    [CmdletBinding()]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')]\n    [OutputType('[PsCustomObject]')]\n    param (\n        [Alias(\"ModuleName\")]\n        [string] $Module = \"*\",\n\n        [switch] $ErrorsOnly,\n\n        [switch] $OutputTotals,\n\n        [switch] $OutputAsObjects,\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    Invoke-TimeSignal -Start\n\n    if (-not (Test-PathExists -Path $PackageDirectory -Type Container)) { return }\n\n    $buildOutputFiles = Get-ChildItem -Path \"$PackageDirectory\\$Module\\BuildModelResult.log\" -ErrorAction SilentlyContinue -Force\n\n    $outputCollection = New-Object System.Collections.Generic.List[System.Object]\n\n    foreach ($result in $buildOutputFiles) {\n        \n        $res = Get-CompilerResult -Path $result.FullName\n\n        if ($null -ne $res) {\n            $outputCollection.Add($res)\n        }\n    }\n\n    $totalErrors = 0\n    $totalWarnings = 0\n\n    $resCol = @($outputCollection.ToArray())\n    \n    $totalWarnings = ($resCol | Measure-Object -Property Warnings -Sum).Sum\n    $totalErrors = ($resCol | Measure-Object -Property Errors -Sum).Sum\n\n    if ($ErrorsOnly) {\n        $resCol = @($resCol | Where-Object Errors -gt 0)\n    }\n\n    if ($OutputAsObjects) {\n        $resCol\n    }\n    else {\n        $resCol | format-table File, @{Label = \"Warnings\"; Expression = { $e = [char]27; $color = \"93\"; \"$e[${color}m$($_.Warnings)${e}[0m\" }; Align = 'right' }, @{Label = \"Errors\"; Expression = { $e = [char]27; $color = \"91\"; \"$e[${color}m$($_.Errors)${e}[0m\" }; Align = 'right' }\n    }\n    \n    if ($OutputTotals) {\n        Write-PSFHostColor -String \"<c='Red'>Total Errors: $totalErrors</c>\"\n        Write-PSFHostColor -String \"<c='Yellow'>Total Warnings: $totalWarnings</c>\"\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365webservertype.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the default web server to be used\n        \n    .DESCRIPTION\n        Get the web server which will be used to run D365FO: Either IIS or IIS Express.\n        Newly deployed development machines will have this set to IIS Express by default.\n        \n        It will look for the file located in the default Package Directory.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365WebServerType\n        \n        This will display the current web server type registered in the \"DynamicsDevConfig.xml\" file.\n        Located in \"K:\\AosService\\PackagesLocalDirectory\\bin\".\n        \n    .NOTES\n        Tag: Web Server, IIS, IIS Express, Development\n        \n        Author: Sander Holvoet (@smholvoet)\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Get-D365WebServerType {\n    [CmdletBinding()]\n    param ()\n\n    if (-not ($script:IsAdminRuntime)) {\n        Write-PSFMessage -Level Host -Message \"The cmdlet needs <c='em'>administrator permission</c> (Run As Administrator) to be able to update the configuration. Please start an <c='em'>elevated</c> session and run the cmdlet again.\"\n        Stop-PSFFunction -Message \"Stopping because the function is not run elevated\"\n        return\n    }\n\n    $filePath = Join-Path -Path (Join-Path -Path $Script:PackageDirectory -ChildPath \"bin\") -ChildPath $Script:DevConfig\n\n    if (-not (Test-PathExists -Path $filePath -Type Leaf)) { return }\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    $namespace = @{ns = \"http://schemas.microsoft.com/dynamics/2012/03/development/configuration\" }\n    $runtimeHostType = Select-Xml -XPath \"/ns:DynamicsDevConfig/ns:RuntimeHostType\" -Path $filePath -Namespace $namespace\n\n    $runtimeHostTypeValue = $runtimeHostType.Node.InnerText\n    [PSCustomObject] @{RuntimeHostType = $runtimeHostTypeValue }\n}"
  },
  {
    "path": "d365fo.tools/functions/get-d365windowsactivationstatus.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get activation status\n        \n    .DESCRIPTION\n        Get all the important license and activation information from the machine\n        \n    .EXAMPLE\n        PS C:\\> Get-D365WindowsActivationStatus\n        \n        This will get the remaining grace and rearm activation information for the machine\n        \n    .NOTES\n        Tags: Windows, License, Activation, Arm, Rearm\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        The cmdlet uses CIM objects to access the activation details\n#>\nfunction Get-D365WindowsActivationStatus {\n    [CmdletBinding()]\n    param ()\n\n    begin {}\n\n    process {\n        $a = Get-CimInstance -Class SoftwareLicensingProduct -Namespace root/cimv2 -ComputerName . -Filter \"Name LIKE '%Windows%'\"\n        $b = Get-CimInstance -Class SoftwareLicensingService -Namespace root/cimv2 -ComputerName .\n\n        $res = [PSCustomObject]@{ Name = $a.Name\n            Description = $a.Description\n            \"Grace Periode (days)\" =  [math]::Round(($a.graceperiodremaining / 1440))\n        }\n\n        $res | Add-Member -MemberType NoteProperty -Name 'ReArms left' -Value $b.RemainingWindowsReArmCount\n \n        $res\n    }\n\n    end {}\n}"
  },
  {
    "path": "d365fo.tools/functions/import-d365aadapplication.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Used to import Aad applications into D365FO\n        \n    .DESCRIPTION\n        Provides a method for importing a AAD application into D365FO.\n        \n    .PARAMETER Name\n        The name that the imported application should have inside the D365FO environment\n        \n    .PARAMETER UserId\n        The id of the user linked to the application inside the D365FO environment\n        \n    .PARAMETER ClientId\n        The Client ID that the imported application should use inside the D365FO environment\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .EXAMPLE\n        PS C:\\> Import-D365AadApplication -Name \"Application1\" -UserId \"admin\" -ClientId \"aef2e67c-64a3-4c72-9294-d288c5bf503d\"\n        \n        Imports Application1 as an application linked to user admin into the D365FO environment.\n        \n    .NOTES\n        Tags: User, Users, Security, Configuration, Permission, AAD, Azure Active Directory, Group, Groups\n        \n        Author: Gert Van Der Heyden (@gertvdheyden)\n        \n        At no circumstances can this cmdlet be used to import users into a PROD environment.\n        \n#>\n\nfunction Import-D365AadApplication {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [String] $Name,\n\n        [Parameter(Mandatory = $true)]\n        [string] $UserId,\n\n        [Parameter(Mandatory = $true)]\n        [string] $ClientId,\n\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword\n    )\n\n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n    $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd\n    }\n\n    $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n\n    try {\n        $sqlCommand.Connection.Open()\n\n        Import-AadApplicationIntoD365FO $SqlCommand $Name $UserId $ClientId\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n        $sqlCommand.Dispose()\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/import-d365aaduser.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Used to import Aad users into D365FO\n        \n    .DESCRIPTION\n        Provides a method for importing a AAD UserGroup or a comma separated list of AadUsers into D365FO.\n        \n    .PARAMETER AadGroupName\n        Azure Active directory user group containing users to be imported\n        \n    .PARAMETER Users\n        Array of users that you want to import into the D365FO environment\n        \n    .PARAMETER StartupCompany\n        Startup company of users imported.\n        \n        Default is DAT\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER IdPrefix\n        A text that will be prefixed into the ID field. E.g. -IdPrefix \"EXT-\" will import users and set ID starting with \"EXT-...\"\n        \n    .PARAMETER NameSuffix\n        A text that will be suffixed into the NAME field. E.g. -NameSuffix \"(Contoso)\" will import users and append \"(Contoso)\"\" to the NAME\n        \n    .PARAMETER IdValue\n        Specify which field to use as ID value when importing the users.\n        Available options 'Login' / 'FirstName' / 'UserPrincipalName'\n        \n        Default is 'Login'\n        \n    .PARAMETER NameValue\n        Specify which field to use as NAME value when importing the users.\n        Available options 'FirstName' / 'DisplayName'\n        \n        Default is 'DisplayName'\n        \n    .PARAMETER AzureAdCredential\n        Use a PSCredential object for connecting with AzureAd\n        \n    .PARAMETER SkipAzureAd\n        Switch to instruct the cmdlet to skip validating against the Azure Active Directory\n        \n    .PARAMETER ForceExactAadGroupName\n        Force to find the exact name of the Azure Active Directory Group\n        \n    .PARAMETER AadGroupId\n        Azure Active directory user group ID containing users to be imported\n        \n    .PARAMETER EmailValue\n        Specify which field to use as EMAIL value when importing the users.\n        Available options 'Mail' / 'UserPrincipalName'\n        \n        Default is 'Mail'\n        \n    .PARAMETER TenantId\n        The TenantId to use when connecting to Azure Active Directory\n        \n        Uses the tenant id of the current environment if not specified.\n        \n    .EXAMPLE\n        PS C:\\> Import-D365AadUser -Users \"Claire@contoso.com\",\"Allen@contoso.com\"\n        \n        Imports Claire and Allen as users\n        \n    .EXAMPLE\n        PS C:\\> $myPassword = ConvertTo-SecureString \"MyPasswordIsSecret\" -AsPlainText -Force\n        PS C:\\> $myCredentials = New-Object System.Management.Automation.PSCredential (\"MyEmailIsAlso\", $myPassword)\n        \n        PS C:\\> Import-D365AadUser -Users \"Claire@contoso.com\",\"Allen@contoso.com\" -AzureAdCredential $myCredentials\n        \n        This will import Claire and Allen as users.\n        \n    .EXAMPLE\n        PS C:\\> Import-D365AadUser -AadGroupName \"CustomerTeam1\"\n        \n        if more than one group match the AadGroupName, you can use the ExactAadGroupName parameter\n        Import-D365AadUser -AadGroupName \"CustomerTeam1\" -ForceExactAadGroupName\n        \n    .EXAMPLE\n        PS C:\\> Import-D365AadUser -AadGroupName \"CustomerTeam1\" -ForceExactAadGroupName\n        \n        This is used to force the cmdlet to find the exact named group in Azure Active Directory.\n        \n    .EXAMPLE\n        PS C:\\> Import-D365AadUser -AadGroupId \"99999999-aaaa-bbbb-cccc-9999999999\"\n        \n        Imports all the users that is present in the AAD Group called CustomerTeam1\n        \n    .EXAMPLE\n        PS C:\\> Import-D365AadUser -Users \"Claire@contoso.com\",\"Allen@contoso.com\" -SkipAzureAd\n        \n        Imports Claire and Allen as users.\n        Will NOT make you connect to the Azure Active Directory(AAD).\n        The needed details will be based on the e-mail address only, and the rest will be blanked.\n        \n    .EXAMPLE\n        PS C:\\> Import-D365AadUser -Users \"Claire@contoso.com\",\"Allen@contoso.com\" -TenantId \"99999999-aaaa-bbbb-cccc-9999999999\"\n        \n        Imports Claire and Allen as users. Uses tenant id \"99999999-aaaa-bbbb-cccc-9999999999\"\n        when connecting to Azure Active Directory(AAD).\n        \n    .NOTES\n        Tags: User, Users, Security, Configuration, Permission, AAD, Azure Active Directory, Group, Groups\n        \n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Charles Colombel (@dropshind)\n        Author: Mötz Jensen (@Splaxi)\n        Author: Miklós Molnár (@scifimiki)\n        Author: Gert Van der Heyden (@gertvdh)\n        Author: Florian Hopfner (@FH-Inway)\n        \n        At no circumstances can this cmdlet be used to import users into a PROD environment.\n        \n        Only users from an Azure Active Directory that you have access to, can be imported.\n        Use AAD B2B implementation if you want to support external people.\n        \n        Every imported users will get the System Administration / Administrator role assigned on import\n        \n#>\n\nfunction Import-D365AadUser {\n    [CmdletBinding(DefaultParameterSetName = 'UserListImport')]\n    param (\n        [Parameter(Mandatory = $true, Position = 1, ParameterSetName = \"GroupNameImport\")]\n        [String] $AadGroupName,\n\n        [Parameter(Mandatory = $true, Position = 1, ParameterSetName = \"UserListImport\")]\n        [string[]]$Users,\n\n        [Parameter(Mandatory = $false, Position = 2)]\n        [string] $StartupCompany = 'DAT',\n\n        [Parameter(Mandatory = $false, Position = 3)]\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Mandatory = $false, Position = 4)]\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false, Position = 5)]\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false, Position = 6)]\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [Parameter(Mandatory = $false, Position = 7)]\n        [string] $IdPrefix = \"\",\n\n        [Parameter(Mandatory = $false, Position = 8)]\n        [string] $NameSuffix = \"\",\n\n        [Parameter(Mandatory = $false, Position = 9)]\n        [ValidateSet('Login', 'FirstName', 'UserPrincipalName')]\n        [string] $IdValue = \"Login\",\n\n        [Parameter(Mandatory = $false, Position = 10)]\n        [ValidateSet('FirstName', 'DisplayName')]\n        [string] $NameValue = \"DisplayName\",\n\n        [Parameter(Mandatory = $false, Position = 11)]\n        [PSCredential] $AzureAdCredential,\n\n        [Parameter(Mandatory = $false, Position = 12, ParameterSetName = \"UserListImport\")]\n        [switch] $SkipAzureAd,\n\n        [Parameter(Mandatory = $false, Position = 13, ParameterSetName = \"GroupNameImport\")]\n        [switch] $ForceExactAadGroupName,\n\n        [Parameter(Mandatory = $true, Position = 14, ParameterSetName = \"GroupIdImport\")]\n        [string] $AadGroupId,\n\n        [Parameter(Mandatory = $false, Position = 15)]\n        [ValidateSet('Mail', 'UserPrincipalName')]\n        [string] $EmailValue = \"Mail\",\n\n        [Parameter(Mandatory = $false, Position = 16)]\n        [string] $TenantId = $Script:TenantId\n    )\n\n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n    $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd\n    }\n\n    $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n\n    $instanceProvider = Get-InstanceIdentityProvider\n    $canonicalProvider = Get-CanonicalIdentityProvider\n\n    try {\n        Write-PSFMessage -Level Verbose -Message \"Trying to connect to the Azure Active Directory with tenant id '$TenantId'\"\n\n        if ($PSBoundParameters.ContainsKey(\"AzureAdCredential\") -eq $true) {\n            Connect-AzAccount -Credential $AzureAdCredential -ErrorAction Stop -TenantId $TenantId\n        }\n        else {\n            if ($SkipAzureAd -eq $false) {\n                Connect-AzAccount -ErrorAction Stop -TenantId $TenantId\n            }\n        }\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while connecting to Azure Active Directory\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n\n    $azureAdUsers = New-Object -TypeName \"System.Collections.ArrayList\"\n\n    $aadUserProperties = @{\n        Property = \"Id as ObjectId\", \"mail\", \"givenName\", \"displayName\", \"userPrincipalName\"\n    }\n    if (( $PSCmdlet.ParameterSetName -eq \"GroupNameImport\") -or ($PSCmdlet.ParameterSetName -eq \"GroupIdImport\")) {\n\n        if ($PSCmdlet.ParameterSetName -eq 'GroupIdImport') {\n            Write-PSFMessage -Level Verbose -Message \"Search AadGroup by its ID : $AadGroupId\"\n\n            $resObj = Invoke-AzRestMethod -Uri \"https://graph.microsoft.com/v1.0/groups/$AadGroupId\"\n\n            if ($resObj.StatusCode -like \"2**\") {\n                $group = $resObj.Content | ConvertFrom-Json\n            }\n        }\n        else {\n            if ($ForceExactAadGroupName) {\n                Write-PSFMessage -Level Verbose -Message \"Search AadGroup by its exactly name : $AadGroupName\"\n\n                $resObj = Invoke-AzRestMethod -Uri \"https://graph.microsoft.com/v1.0/groups?`$filter=DisplayName eq '$AadGroupName'\"\n\n                if ($resObj.StatusCode -like \"2**\") {\n                    $group = $resObj.Content | ConvertFrom-Json | Select-Object -ExpandProperty value\n                }\n            }\n            else {\n                Write-PSFMessage -Level Verbose -Message \"Search AadGroup by searching with its name : $AadGroupName\"\n\n                $resObj = Invoke-AzRestMethod -Uri \"https://graph.microsoft.com/v1.0/groups?`$filter=startswith(DisplayName,'$AadGroupName')\"\n\n                if ($resObj.StatusCode -like \"2**\") {\n                    $group = $resObj.Content | ConvertFrom-Json | Select-Object -ExpandProperty value\n                }\n            }\n        }\n\n        if ($null -eq $group) {\n            Write-PSFMessage -Level Host -Message \"Unable to find the specified group in the AAD. Please ensure the group exists and that you have enough permissions to access it.\"\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n        else {\n            Write-PSFMessage -Level Host -Message \"Processing Azure AD user Group `\"$($group[0].DisplayName)`\"\"\n        }\n\n        if ($group.Length -gt 1) {\n            Write-PSFMessage -Level Host -Message \"More than one group found\"\n            foreach ($foundGroup in $group) {\n                Write-PSFMessage -Level Host -Message \"Group found $($foundGroup.DisplayName)\"\n            }\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n\n        $resMembersObj = Invoke-AzRestMethod -Uri \"https://graph.microsoft.com/v1.0/groups/$($group.id)/members\"\n\n        if ($resMembersObj.StatusCode -like \"2**\") {\n            $userlist = $resMembersObj.Content | ConvertFrom-Json | Select-Object -ExpandProperty value\n        }\n\n        foreach ($user in $userlist) {\n            if ($user.'@odata.type' -eq \"#microsoft.graph.user\") {\n\n                $resObj = Invoke-AzRestMethod -Uri \"https://graph.microsoft.com/v1.0/users/$($user.id)\"\n\n                if ($resObj.StatusCode -like \"2**\") {\n                    $azureAdUser = $resObj.Content |\n                        ConvertFrom-Json |\n                        Select-Object -First 1 |\n                        Select-PSFObject @aadUserProperties\n                }\n\n                if ($null -eq $azureAdUser.mail) {\n                    Write-PSFMessage -Level Critical \"User $($user.ObjectId) did not have an Mail\"\n                }\n                else {\n                    $null = $azureAdUsers.Add($azureAdUser)\n                }\n            }\n        }\n    }\n    else {\n        foreach ($user in $Users) {\n\n            if ($SkipAzureAd -eq $true) {\n                $name = Get-LoginFromEmail $user\n                $null = $azureAdUsers.Add([PSCustomObject]@{\n                        mail              = $user\n                        givenName         = $name\n                        displayName       = $name\n                        ObjectId          = ''\n                        userPrincipalName = $user\n                    })\n            }\n            else {\n                $resObj = Invoke-AzRestMethod -Uri \"https://graph.microsoft.com/v1.0/users?`$filter=mail eq '$user' or userPrincipalName eq '$user'\"\n\n                if ($resObj.StatusCode -like \"2**\") {\n                    $aadUser = $resObj.Content |\n                        ConvertFrom-Json |\n                        Select-Object -ExpandProperty value |\n                        Select-Object -First 1 |\n                        Select-PSFObject @aadUserProperties\n                }\n\n                if ($null -eq $aadUser) {\n                    Write-PSFMessage -Level Critical \"Could not find user $user in AzureAAd\"\n                }\n                else {\n                    $null = $azureAdUsers.Add($aadUser)\n                }\n            }\n        }\n    }\n\n    try {\n        $sqlCommand.Connection.Open()\n\n        foreach ($user in $azureAdUsers) {\n\n            $identityProvider = $canonicalProvider\n\n            Write-PSFMessage -Level Verbose -Message \"Getting tenant from $($user.Mail).\"\n            $tenant = Get-TenantFromEmail $user.Mail\n\n            Write-PSFMessage -Level Verbose -Message \"Getting domain from $($user.Mail).\"\n            $networkDomain = Get-NetworkDomain $user.Mail\n\n            Write-PSFMessage -Level Verbose -Message \"InstanceProvider : $InstanceProvider\"\n            Write-PSFMessage -Level Verbose -Message \"Tenant : $Tenant\"\n\n            if ($user.Mail.ToLower().Contains(\"outlook.com\") -eq $true) {\n                $identityProvider = \"live.com\"\n            }\n            else {\n                if ($instanceProvider.ToLower().Contains($tenant.ToLower()) -ne $True) {\n                    Write-PSFMessage -Level Verbose -Message \"Getting identity provider from  $($user.Mail).\"\n                    $identityProvider = Get-IdentityProvider $user.Mail\n                }\n            }\n\n            Write-PSFMessage -Level Verbose -Message \"Getting sid from  $($user.Mail) and identity provider : $identityProvider.\"\n            $sid = Get-UserSIDFromAad $user.Mail $identityProvider\n            Write-PSFMessage -Level Verbose -Message \"Generated SID : $sid\"\n            $id = \"\"\n            if ($IdValue -eq 'Login') {\n                $id = $IdPrefix + $(Get-LoginFromEmail $user.Mail)\n            }\n            elseif ($IdValue -eq 'UserPrincipalName') {\n                $id = $IdPrefix + $user.UserPrincipalName\n            }\n            else {\n                $id = $IdPrefix + $user.GivenName\n            }\n\n            if ($id.Length -gt 20) {\n                $oldId = $id\n                $id = $id -replace '^(.{0,20}).*', '$1'\n                Write-PSFMessage -Level Host -Message \"The id <c='em'>'$oldId'</c> does not fit the <c='em'>20 character limit</c> on UserInfo table's ID field and will be truncated to <c='em'>'$id'</c>\"\n            }\n\n\n            $name = \"\"\n            if ($NameValue -eq 'DisplayName') {\n                $name = $user.DisplayName + $NameSuffix\n            }\n            else {\n                $name = $user.GivenName + $NameSuffix\n            }\n\n            $email = \"\"\n            if ($EmailValue -eq 'Mail') {\n                $email = $user.Mail\n            }\n            else {\n                $email = $user.UserPrincipalName\n            }\n\n            Write-PSFMessage -Level Verbose -Message \"Id for user $email : $id\"\n            Write-PSFMessage -Level Verbose -Message \"Name for user $email : $name\"\n            Write-PSFMessage -Level Verbose -Message \"Importing $email - SID $sid - Provider $identityProvider\"\n\n            Import-AadUserIntoD365FO $SqlCommand $email $name $id $sid $StartupCompany $identityProvider $networkDomain $user.ObjectId\n\n            if (Test-PSFFunctionInterrupt) { return }\n        }\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n        $sqlCommand.Dispose()\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/import-d365bacpac.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Import a bacpac file\n        \n    .DESCRIPTION\n        Import a bacpac file to either a Tier1 or Tier2 environment\n        \n    .PARAMETER ImportModeTier1\n        Switch to instruct the cmdlet that it will import into a Tier1 environment\n        \n        The cmdlet will expect to work against a SQL Server instance\n        \n    .PARAMETER ImportModeTier2\n        Switch to instruct the cmdlet that it will import into a Tier2 environment\n        \n        The cmdlet will expect to work against an Azure DB instance\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER BacpacFile\n        Path to the bacpac file you want to import into the database server\n        \n    .PARAMETER NewDatabaseName\n        Name of the new database that will be created while importing the bacpac file\n        \n        This will create a new database on the database server and import the content of the bacpac into\n        \n    .PARAMETER AxDeployExtUserPwd\n        Password that is obtained from LCS\n        \n    .PARAMETER AxDbAdminPwd\n        Password that is obtained from LCS\n        \n    .PARAMETER AxRuntimeUserPwd\n        Password that is obtained from LCS\n        \n    .PARAMETER AxMrRuntimeUserPwd\n        Password that is obtained from LCS\n        \n    .PARAMETER AxRetailRuntimeUserPwd\n        Password that is obtained from LCS\n        \n    .PARAMETER AxRetailDataSyncUserPwd\n        Password that is obtained from LCS\n        \n    .PARAMETER AxDbReadonlyUserPwd\n        Password that is obtained from LCS\n        \n    .PARAMETER CustomSqlFile\n        Path to the sql script file that you want the cmdlet to execute against your data after it has been imported\n        \n    .PARAMETER ModelFile\n        Path to the model file that you want the SqlPackage.exe to use instead the one being part of the bacpac file\n        \n        This is used to override SQL Server options, like collation and etc\n        \n    .PARAMETER DiagnosticFile\n        Path to where you want the import to output a diagnostics file to assist you in troubleshooting the import\n        \n    .PARAMETER ImportOnly\n        Switch to instruct the cmdlet to only import the bacpac into the new database\n        \n        The cmdlet will create a new database and import the content of the bacpac file into this\n        \n        Nothing else will be executed\n        \n    .PARAMETER MaxParallelism\n        Sets SqlPackage.exe's degree of parallelism for concurrent operations running against a database\n        \n        The default value is 8\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .PARAMETER Properties\n        String array of properties to be used by SQLPackage.exe\n        See https://learn.microsoft.com/en-us/sql/tools/sqlpackage/sqlpackage-import#properties-specific-to-the-import-action for more information.\n        Note that some properties are already set by the cmdlet, and cannot be overridden.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365InstallSqlPackage\n        \n        You should always install the latest version of the SqlPackage.exe, which is used by New-D365Bacpac.\n        \n        This will fetch the latest .Net Core Version of SqlPackage.exe and install it at \"C:\\temp\\d365fo.tools\\SqlPackage\".\n        \n    .EXAMPLE\n        PS C:\\> Import-D365Bacpac -ImportModeTier1 -BacpacFile \"C:\\temp\\uat.bacpac\" -NewDatabaseName \"ImportedDatabase\"\n        PS C:\\> Switch-D365ActiveDatabase -NewDatabaseName \"ImportedDatabase\"\n        \n        This will instruct the cmdlet that the import will be working against a SQL Server instance.\n        It will import the \"C:\\temp\\uat.bacpac\" file into a new database named \"ImportedDatabase\".\n        The next thing to do is to switch the active database out with the new one you just imported.\n        \"ImportedDatabase\" will be switched in as the active database, while the old one will be named \"AXDB_original\".\n        \n    .EXAMPLE\n        PS C:\\> Import-D365Bacpac -ImportModeTier2 -SqlUser \"sqladmin\" -SqlPwd \"XyzXyz\" -BacpacFile \"C:\\temp\\uat.bacpac\" -AxDeployExtUserPwd \"XxXx\" -AxDbAdminPwd \"XxXx\" -AxRuntimeUserPwd \"XxXx\" -AxMrRuntimeUserPwd \"XxXx\" -AxRetailRuntimeUserPwd \"XxXx\" -AxRetailDataSyncUserPwd \"XxXx\" -AxDbReadonlyUserPwd \"XxXx\" -NewDatabaseName \"ImportedDatabase\"\n        PS C:\\> Switch-D365ActiveDatabase -NewDatabaseName \"ImportedDatabase\" -SqlUser \"sqladmin\" -SqlPwd \"XyzXyz\"\n        \n        This will instruct the cmdlet that the import will be working against an Azure DB instance.\n        It requires all relevant passwords from LCS for all the builtin user accounts used in a Tier 2 environment.\n        It will import the \"C:\\temp\\uat.bacpac\" file into a new database named \"ImportedDatabase\".\n        The next thing to do is to switch the active database out with the new one you just imported.\n        \"ImportedDatabase\" will be switched in as the active database, while the old one will be named \"AXDB_original\".\n        \n    .EXAMPLE\n        PS C:\\> Import-D365Bacpac -ImportModeTier1 -BacpacFile \"C:\\temp\\uat.bacpac\" -NewDatabaseName \"ImportedDatabase\" -DiagnosticFile \"C:\\temp\\ImportLog.txt\"\n        \n        This will instruct the cmdlet that the import will be working against a SQL Server instance.\n        It will import the \"C:\\temp\\uat.bacpac\" file into a new database named \"ImportedDatabase\".\n        It will output a diagnostic file to \"C:\\temp\\ImportLog.txt\".\n        \n    .EXAMPLE\n        PS C:\\> Import-D365Bacpac -ImportModeTier1 -BacpacFile \"C:\\temp\\uat.bacpac\" -NewDatabaseName \"ImportedDatabase\" -DiagnosticFile \"C:\\temp\\ImportLog.txt\" -MaxParallelism 32\n        \n        This will instruct the cmdlet that the import will be working against a SQL Server instance.\n        It will import the \"C:\\temp\\uat.bacpac\" file into a new database named \"ImportedDatabase\".\n        It will output a diagnostic file to \"C:\\temp\\ImportLog.txt\".\n        \n        It will use 32 connections against the database server while importing the bacpac file.\n        \n    .EXAMPLE\n        PS C:\\> Import-D365Bacpac -ImportModeTier1 -BacpacFile \"C:\\temp\\uat.bacpac\" -NewDatabaseName \"ImportedDatabase\" -ImportOnly\n        \n        This will instruct the cmdlet that the import will be working against a SQL Server instance.\n        It will import the \"C:\\temp\\uat.bacpac\" file into a new database named \"ImportedDatabase\".\n        No cleanup or prepping jobs will be executed, because this is for importing only.\n        \n        This would be something that you can use when extract a bacpac file from a Tier1 and want to import it into a Tier1.\n        You would still need to execute the Switch-D365ActiveDatabase cmdlet, to get the newly imported database to be the AXDB database.\n        \n    .EXAMPLE\n        PS C:\\> [System.Collections.ArrayList] $PropertiesList = New-Object -TypeName \"System.Collections.ArrayList\"\n        PS C:\\> $PropertiesList.Add(\"DisableIndexesForDataPhase=false\")\n        PS C:\\> Import-D365Bacpac -ImportModeTier1 -BacpacFile \"C:\\temp\\uat.bacpac\" -NewDatabaseName \"ImportedDatabase\" -Properties $PropertiesList.ToArray()\n        \n        This will instruct the cmdlet that the import will be working against a SQL Server instance.\n        It will import the \"C:\\temp\\uat.bacpac\" file into a new database named \"ImportedDatabase\".\n        It will use the DisableIndexesForDataPhase SQLPackage property to disable the index rebuild during the data phase of the import.\n        \n    .NOTES\n        Tags: Database, Bacpac, Tier1, Tier2, Golden Config, Config, Configuration\n        \n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Import-D365Bacpac {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseProcessBlockForPipelineCommand\", \"\")]\n    [CmdletBinding(DefaultParameterSetName = 'ImportTier1')]\n    param (\n        [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier1', Position = 0)]\n        [switch] $ImportModeTier1,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', Position = 0)]\n        [Parameter(Mandatory = $true, ParameterSetName = 'ImportOnlyTier2', Position = 0)]\n        [switch] $ImportModeTier2,\n\n        [Parameter(Position = 1 )]\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Position = 2 )]\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false, Position = 3 )]\n        [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 3)]\n        [Parameter(Mandatory = $false, ParameterSetName = 'ImportTier1', Position = 3)]\n        [Parameter(Mandatory = $true, ParameterSetName = 'ImportOnlyTier2', ValueFromPipelineByPropertyName = $true, Position = 3)]\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false, Position = 4 )]\n        [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 4)]\n        [Parameter(Mandatory = $false, ParameterSetName = 'ImportTier1', Position = 4)]\n        [Parameter(Mandatory = $true, ParameterSetName = 'ImportOnlyTier2', ValueFromPipelineByPropertyName = $true, Position = 4)]\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 5 )]\n        [Alias('File')]\n        [string] $BacpacFile,\n\n        [Parameter(Mandatory = $true, Position = 6 )]\n        [string] $NewDatabaseName,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 7)]\n        [Parameter(Mandatory = $false, ParameterSetName = 'ImportOnlyTier2', Position = 7)]\n        [string] $AxDeployExtUserPwd,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 8)]\n        [Parameter(Mandatory = $false, ParameterSetName = 'ImportOnlyTier2', Position = 8)]\n        [string] $AxDbAdminPwd,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 9)]\n        [Parameter(Mandatory = $false, ParameterSetName = 'ImportOnlyTier2', Position = 9)]\n        [string] $AxRuntimeUserPwd,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 10)]\n        [Parameter(Mandatory = $false, ParameterSetName = 'ImportOnlyTier2', Position = 10)]\n        [string] $AxMrRuntimeUserPwd,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 11)]\n        [Parameter(Mandatory = $false, ParameterSetName = 'ImportOnlyTier2', Position = 11)]\n        [string] $AxRetailRuntimeUserPwd,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 12)]\n        [Parameter(Mandatory = $false, ParameterSetName = 'ImportOnlyTier2', Position = 12)]\n        [string] $AxRetailDataSyncUserPwd,\n        \n        [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 13)]\n        [Parameter(Mandatory = $false, ParameterSetName = 'ImportOnlyTier2', Position = 13)]\n        [string] $AxDbReadonlyUserPwd,\n        \n        [string] $CustomSqlFile,\n\n        [string] $ModelFile,\n\n        [string] $DiagnosticFile,\n \n        [Parameter(Mandatory = $false, ParameterSetName = 'ImportTier1')]\n        [Parameter(Mandatory = $true, ParameterSetName = 'ImportOnlyTier2')]\n        [switch] $ImportOnly,\n        \n        [int] $MaxParallelism = 8,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ImportBacpac\"),\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly,\n\n        [switch] $EnableException,\n\n        [string[]] $Properties\n    )\n\n    if (-not (Test-PathExists -Path $BacpacFile -Type Leaf)) {\n        return\n    }\n\n    if ($PSBoundParameters.ContainsKey(\"CustomSqlFile\")) {\n        if (-not (Test-PathExists -Path $CustomSqlFile -Type Leaf)) {\n            return\n        }\n        else {\n            $ExecuteCustomSQL = $true\n        }\n    }\n\n    Invoke-TimeSignal -Start\n    \n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n    $BaseParams = @{\n        DatabaseServer = $DatabaseServer\n        DatabaseName   = $DatabaseName\n        SqlUser        = $SqlUser\n        SqlPwd         = $SqlPwd\n    }\n\n    $ImportParams = @{\n        Action   = \"import\"\n        FilePath = $BacpacFile\n        MaxParallelism = $MaxParallelism\n    }\n\n    if (-not [system.string]::IsNullOrEmpty($DiagnosticFile)) {\n        if (-not (Test-PathExists -Path (Split-Path $DiagnosticFile -Parent) -Type Container -Create)) { return }\n        $ImportParams.DiagnosticFile = $DiagnosticFile\n    }\n\n    if (-not [system.string]::IsNullOrEmpty($ModelFile)) {\n        if (-not (Test-PathExists -Path $ModelFile -Type Leaf)) { return }\n\n        $ImportParams.ModelFile = $ModelFile\n    }\n\n    [System.Collections.ArrayList] $PropertiesList = New-Object -TypeName \"System.Collections.ArrayList\"\n    foreach ($item in $Properties) {\n        $PropertiesList.Add($item) > $null\n    }\n\n    Write-PSFMessage -Level Verbose \"Testing if we are working against a Tier2 / Azure DB\"\n    if ($ImportModeTier2) {\n        Write-PSFMessage -Level Verbose \"Start collecting the current Azure DB instance settings\"\n\n        $Objectives = Get-AzureServiceObjective @BaseParams\n\n        if ($null -eq $Objectives) { return }\n\n        $null = $PropertiesList.Add(\"DatabaseEdition=$($Objectives.DatabaseEdition)\")\n        $null = $PropertiesList.Add(\"DatabaseServiceObjective=$($Objectives.DatabaseServiceObjective)\")\n    }\n    $ImportParams.Properties = $PropertiesList.ToArray()\n    \n    $Params = Get-DeepClone $BaseParams\n    $Params.DatabaseName = $NewDatabaseName\n    $Params.TrustedConnection = $UseTrustedConnection\n\n    $SqlPackageParams = Get-DeepClone $Params\n    $SqlPackageParams.OutputCommandOnly = $OutputCommandOnly\n    $SqlPackageParams.LogPath = $LogPath\n    $SqlPackageParams.ShowOriginalProgress = $ShowOriginalProgress\n    \n    Write-PSFMessage -Level Verbose \"Start importing the bacpac with a new database name and current settings\"\n    Invoke-SqlPackage @SqlPackageParams @ImportParams\n\n    if ($OutputCommandOnly) { return }\n\n    if ($ImportOnly) { return }\n\n    if (Test-PSFFunctionInterrupt) { return }\n    \n    Write-PSFMessage -Level Verbose \"Importing completed\"\n\n    Write-PSFMessage -Level Verbose -Message \"Start working on the configuring the new database\"\n\n    if ($ImportModeTier2) {\n        Write-PSFMessage -Level Verbose \"Building sql statement to update the imported Azure database\"\n\n        $InstanceValues = Get-InstanceValues @BaseParams -TrustedConnection $UseTrustedConnection\n\n        if ($null -eq $InstanceValues) { return }\n\n        $AzureParams = @{\n            AxDeployExtUserPwd = $AxDeployExtUserPwd; AxDbAdminPwd = $AxDbAdminPwd;\n            AxRuntimeUserPwd = $AxRuntimeUserPwd; AxMrRuntimeUserPwd = $AxMrRuntimeUserPwd;\n            AxRetailRuntimeUserPwd = $AxRetailRuntimeUserPwd; AxRetailDataSyncUserPwd = $AxRetailDataSyncUserPwd;\n            AxDbReadonlyUserPwd = $AxDbReadonlyUserPwd;\n        }\n\n        $res = Set-AzureBacpacValues @Params @AzureParams @InstanceValues\n\n        if (-not ($res)) { return }\n    }\n    else {\n        Write-PSFMessage -Level Verbose \"Building sql statement to update the imported SQL database\"\n\n        $res = Set-SqlBacpacValues @Params\n            \n        if (-not ($res)) { return }\n    }\n\n    if ($ExecuteCustomSQL) {\n        Write-PSFMessage -Level Verbose -Message \"Invoking the Execution of custom SQL script\"\n        $res = Invoke-D365SqlScript @Params -FilePath $CustomSqlFile\n\n        if (-not ($res)) { return }\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/import-d365dacpac.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Import dacpac file to a database\n        \n    .DESCRIPTION\n        Import a dacpac file into a database, using the publish feature of SqlPackage.exe\n        \n        If the database doesn't exists, it will be created\n        \n        If the database exists, the publish process from the dacpac file will make sure to align the different tables inside the database\n        \n    .PARAMETER Path\n        Path to the dacpac file that you want to import\n        \n    .PARAMETER ModelFile\n        Path to the model file that you want the SqlPackage.exe to use instead the one being part of the dacpac file\n        \n        This is used to override SQL Server options, like collation and etc\n        \n        This is also used to support single table import / restore from a dacpac file\n        \n    .PARAMETER PublishFile\n        Path to the publish / profile file that contains extended parameters for the SqlPackage.exe assembly\n        \n    .PARAMETER DiagnosticFile\n        Path to where you want the import to output a diagnostics file to assist you in troubleshooting the import\n        \n    .PARAMETER MaxParallelism\n        Sets SqlPackage.exe's degree of parallelism for concurrent operations running against a database\n        \n        The default value is 8\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Import-D365Dacpac -Path \"c:\\Temp\\AxDB.dacpac\" -ModelFile \"c:\\Temp\\dbo.salestable.model.xml\"\n        \n        This will import the dacpac file and use the modified model file while doing so.\n        It will use the \"c:\\Temp\\AxDB.dacpac\" as the Path parameter.\n        It will use the \"c:\\Temp\\dbo.salestable.model.xml\" as the ModelFile parameter.\n        \n        This is used to enable single table restore / publish.\n        \n    .EXAMPLE\n        PS C:\\> Import-D365Dacpac -Path \"c:\\Temp\\AxDB.dacpac\" -ModelFile \"c:\\Temp\\dbo.salestable.model.xml\" -DiagnosticFile \"C:\\temp\\ImportLog.txt\" -MaxParallelism 32\n        \n        This will import the dacpac file and use the modified model file while doing so.\n        It will use the \"c:\\Temp\\AxDB.dacpac\" as the Path parameter.\n        It will use the \"c:\\Temp\\dbo.salestable.model.xml\" as the ModelFile parameter.\n        It will use the \"C:\\temp\\ImportLog.txt\" as the DiagnosticFile parameter, where the diagnostic file will be stored.\n        \n        It will use 32 connections against the database server while importing the bacpac file.\n        \n        This is used to enable single table restore / publish.\n        \n    .EXAMPLE\n        PS C:\\> Import-D365Dacpac -Path \"c:\\Temp\\AxDB.dacpac\" -PublishFile \"c:\\Temp\\publish.xml\"\n        \n        This will import the dacpac file and use the Publish file which contains advanced configuration instructions for SqlPackage.exe.\n        It will use the \"c:\\Temp\\AxDB.dacpac\" as the Path parameter.\n        It will use the \"c:\\Temp\\publish.xml\" as the PublishFile parameter, which contains advanced configuration instructions for SqlPackage.exe.\n        \n        This is used to enable full restore / publish, but to avoid some of the common pitfalls.\n        \n    .NOTES\n        Tags: Database, Dacpac, Tier1, Tier2, Golden Config, Config, Configuration\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Import-D365Dacpac {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [Alias(\"Dacpac\")]\n        [Alias(\"File\")]\n        [string] $Path,\n\n        [string] $ModelFile,\n\n        [Alias(\"ProfileFile\")]\n        [string] $PublishFile,\n\n        [string] $DiagnosticFile,\n\n        [int] $MaxParallelism = 8,\n\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ImportDacpac\"),\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly,\n\n        [switch] $EnableException\n    )\n\n    if (-not (Test-PathExists -Path $Path -Type Leaf)) {\n        return\n    }\n\n    Invoke-TimeSignal -Start\n    \n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n    $BaseParams = @{\n        DatabaseServer = $DatabaseServer\n        DatabaseName   = $DatabaseName\n        SqlUser        = $SqlUser\n        SqlPwd         = $SqlPwd\n    }\n\n    $ImportParams = @{\n        Action         = \"Publish\"\n        FilePath       = $Path\n        MaxParallelism = $MaxParallelism\n    }\n\n    if ($DiagnosticFile) {\n        if (-not (Test-PathExists -Path (Split-Path $DiagnosticFile -Parent) -Type Container -Create)) { return }\n        \n        $ImportParams.DiagnosticFile = $DiagnosticFile\n    }\n\n    if ($ModelFile) {\n        if (-not (Test-PathExists -Path $ModelFile -Type Leaf)) { return }\n\n        $ImportParams.ModelFile = $ModelFile\n    }\n\n    if ($PublishFile) {\n        if (-not (Test-PathExists -Path $PublishFile -Type Leaf)) { return }\n\n        $ImportParams.PublishFile = $PublishFile\n    }\n\n    if (Test-PSFFunctionInterrupt) { return }\n    \n    Write-PSFMessage -Level Verbose \"Start publishing the dacpac\"\n    Invoke-SqlPackage @BaseParams @ImportParams -TrustedConnection $UseTrustedConnection -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n\n    if ($OutputCommandOnly) { return }\n\n    if (Test-PSFFunctionInterrupt) { return }\n    \n    Write-PSFMessage -Level Verbose \"Importing completed\"\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/import-d365externaluser.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Import an user from an external Azure Active Directory (AAD)\n        \n    .DESCRIPTION\n        Imports an user from an AAD that is NOT the same as the AAD tenant that the D365FO environment is running under\n        \n    .PARAMETER Id\n        The internal Id that the user must be imported with\n        \n        The Id has to unique across the entire user base\n        \n    .PARAMETER Name\n        The display name of the user inside the D365FO environment\n        \n    .PARAMETER Email\n        The email address of the user that you want to import\n        \n        This is also the sign-in user name / e-mail address to gain access to the system\n        \n        If the external AAD tenant has multiple custom domain names, you have to use the domain that they have configured as default\n        \n    .PARAMETER Company\n        Default company that should be configured for the user, for when they sign-in to the D365 environment\n        \n        Default value is \"DAT\"\n        \n    .PARAMETER Language\n        Language that should be configured for the user, for when they sign-in to the D365 environment\n        \n        Default value is \"en-US\"\n        \n    .PARAMETER Enabled\n        Should the imported user be enabled or not?\n        \n        Default value is 1, which equals true / yes\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .EXAMPLE\n        PS C:\\> Import-D365ExternalUser -Id \"John\" -Name \"John Doe\" -Email \"John@contoso.com\"\n        \n        This will import an user from an external Azure Active Directory.\n        The new user will get the system wide Id \"John\".\n        The name of the new user will be \"John Doe\".\n        The e-mail address / sign-in e-mail address will be registered as \"John@contoso.com\".\n        \n    .NOTES\n        Tags: User, Users, Security, Configuration, Permission, AAD, Azure Active Directory\n        \n        Author: Anderson Joyle (@AndersonJoyle)\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Import-D365ExternalUser {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $Id,\n\n        [Parameter(Mandatory = $true)]\n        [string] $Name,\n\n        [Parameter(Mandatory = $true)]\n        [string] $Email,\n\n        [Parameter(Mandatory = $false)]\n        [int] $Enabled = 1,\n\n        [Parameter(Mandatory = $false)]\n        [string] $Company = \"DAT\",\n\n        [Parameter(Mandatory = $false)]\n        [string] $Language = \"en-us\",\n\n        [Parameter(Mandatory = $false)]\n        [string]$DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Mandatory = $false)]\n        [string]$DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false)]\n        [string]$SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false)]\n        [string]$SqlPwd = $Script:DatabaseUserPassword\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n\n        $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n        $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n            SqlUser = $SqlUser; SqlPwd = $SqlPwd\n        }\n\n        $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n\n        try {\n            $sqlCommand.Connection.Open()\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        try {\n            $userAuth = Get-D365UserAuthenticationDetail $Email\n\n            $provider = $userAuth.IdentityProvider\n            $networkDomain = $userAuth.NetworkDomain\n            $sid = $userAuth.SID\n            \n            Write-PSFMessage -Level Verbose -Message \"Extracted sid: $sid\"\n\n            Import-AadUserIntoD365FO -SqlCommand $SqlCommand -SignInName $Email -Name $Name -Id $Id -SID $SID -StartUpCompany $Company -IdentityProvider $provider -NetworkDomain $networkDomain -Language $Language\n\n            if (Test-PSFFunctionInterrupt) { return }\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n        finally {\n            if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n                $sqlCommand.Connection.Close()\n            }\n            $sqlCommand.Dispose()\n        }\n    }\n\n    end {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/import-d365model.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Import a model into Dynamics 365 for Finance & Operations\n        \n    .DESCRIPTION\n        Import a model into a Dynamics 365 for Finance & Operations environment\n        \n    .PARAMETER Path\n        Path to the axmodel file that you want to import\n        \n    .PARAMETER Model\n        Name of the model that you want to work against\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the AOS service PackagesLocalDirectory\\bin\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER Replace\n        Instruct the cmdlet to replace an already existing model\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .EXAMPLE\n        PS C:\\> Import-D365Model -Path c:\\temp\\d365fo.tools\\CustomModel.axmodel\n        \n        This will import the \"c:\\temp\\d365fo.tools\\CustomModel.axmodel\" model into the PackagesLocalDirectory location.\n        \n    .EXAMPLE\n        PS C:\\> Import-D365Model -Path c:\\temp\\d365fo.tools\\CustomModel.axmodel -Replace\n        \n        This will import the \"c:\\temp\\d365fo.tools\\CustomModel.axmodel\" model into the PackagesLocalDirectory location.\n        If the model already exists it will replace it.\n        \n    .NOTES\n        Tags: ModelUtil, Axmodel, Model, Import, Replace, Source Control, Vsts, Azure DevOps\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Import-D365Model {\n    # [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidDefaultValueSwitchParameter\", \"\")]\n    [CmdletBinding()]\n    \n    param (\n        [Parameter(Mandatory = $True, Position = 1 )]\n        [Alias('File')]\n        [string] $Path,\n\n        [Parameter(Mandatory = $false, Position = 2 )]\n        [string] $BinDir = \"$Script:PackageDirectory\\bin\",\n\n        [Parameter(Mandatory = $false, Position = 3 )]\n        [string] $MetaDataDir = \"$Script:MetaDataDir\",\n\n        [switch] $Replace,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModelUtilImport\"),\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly\n    )\n\n    Invoke-TimeSignal -Start\n    \n    if($Replace) {\n        Invoke-ModelUtil -Command \"Replace\" -Path $Path -BinDir $BinDir -MetaDataDir $MetaDataDir -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n    }\n    else {\n        Invoke-ModelUtil -Command \"Import\" -Path $Path -BinDir $BinDir -MetaDataDir $MetaDataDir -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/import-d365rsatselfservicecertificates.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Import certificates for RSAT\n        \n    .DESCRIPTION\n        Import the certificates for RSAT into the correct stores and display the thumbprint\n        \n        When working with self-service environments you need to download a zip file from LCS. The zip file needs to be unblocked and then extracted into a folder, with only the .cer and the .pxf files inside\n        \n    .PARAMETER Path\n        Path to the folder where the .cer and .pxf files are located\n        \n        The files needs to be extracted from the zip archive\n        \n    .PARAMETER Password\n        Password for the .pxf file\n        \n        Working with self-service environments, the password will be displayed during the download of the zip archive\n        \n    .EXAMPLE\n        PS C:\\> Import-D365RsatSelfServiceCertificates -Path \"C:\\Temp\\UAT\" -Password \"123456789\"\n        \n        This will import the .cer and .pxf files into the correct store, bases on the files located in \"C:\\Temp\\UAT\".\n        After import it will display the thumbprint for both certificates.\n        \n        Sample output:\n        [23:43:05][Import-D365RsatSelfServiceCertificates] Pfx Thumbprint:  B4D6921321434235463463414312343253523A05\n        [23:43:05][Import-D365RsatSelfServiceCertificates] Cert Thumbprint: B4D6921321434235463463414312343253523A05\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Import-D365RsatSelfServiceCertificates {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidUsingConvertToSecureStringWithPlainText\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidUsingPlainTextForPassword\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(\n            Mandatory = $true,\n            ValueFromPipelineByPropertyName = $true)]\n        [ValidateNotNullOrEmpty()]\n        [string] $Path,\n\n        [Parameter(\n            Mandatory = $true,\n            ValueFromPipelineByPropertyName = $true)]\n        [ValidateNotNullOrEmpty()]\n        [string] $Password\n    )\n    \n    begin {\n        \n    }\n    \n    process {\n        [Security.SecureString] $PasswordSecure = (ConvertTo-SecureString -String $Password -Force -AsPlainText)\n    \n        if (-not (Test-PathExists -Path $Path -Type Container)) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        $pathCertFile = (Get-ChildItem -Path \"$Path\\*.cer\" | Select-Object -First 1).FullName\n        $pathPfxFile = (Get-ChildItem -Path \"$Path\\*.pfx\" | Select-Object -First 1).FullName\n\n        if (-not $pathCertFile -or -not $pathPfxFile) {\n            $messageString = \"One of the certificate files are <c='em'>missing</c>. Make sure that the path you supplied contains a set of <c='em'>.cer</c> and <c='em'>.pxf</c> certificate files.\"\n            Write-PSFMessage -Level Host -Message $messageString\n            Stop-PSFFunction -Message \"Stopping because an generic error message.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', '')))\n            return\n        }\n\n        $pxfCert = Import-PfxCertificate -FilePath $pathPfxFile -CertStoreLocation \"Cert:\\LocalMachine\\Root\" -Password $PasswordSecure\n        Import-PfxCertificate -FilePath $pathPfxFile -CertStoreLocation \"Cert:\\LocalMachine\\My\" -Password $PasswordSecure > $null\n        $cert = Import-Certificate -FilePath $pathCertFile -CertStoreLocation \"Cert:\\LocalMachine\\Root\"\n        Import-Certificate -FilePath $pathCertFile -CertStoreLocation \"Cert:\\LocalMachine\\My\" > $null\n\n        Write-PSFMessage -Level Host -Message \"Pfx Thumbprint: <c='em'>$($pxfCert.Thumbprint)</c>\"\n        Write-PSFMessage -Level Host -Message \"Cert Thumbprint: <c='em'>$($cert.Thumbprint)</c>\"\n\n    }\n    \n    end {\n        \n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/initialize-d365rsatcertificate.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Create and configure test automation certificate\n        \n    .DESCRIPTION\n        Creates a new self signed certificate for automated testing and reconfigures the AOS Windows Identity Foundation configuration to trust the certificate\n        \n    .PARAMETER CertificateFileName\n        Filename to be used when exporting the cer file\n        \n    .PARAMETER PrivateKeyFileName\n        Filename to be used when exporting the pfx file\n        \n    .PARAMETER Password\n        The password that you want to use to protect your certificate with\n        \n        The default value is: \"Password1\"\n        \n    .PARAMETER CertificateOnly\n        Switch specifying if only the certificate needs to be created\n        \n        If specified, then only the certificate is created and the thumbprint is not added to the wif.config on the AOS side\n        If not specified (default) then the certificate is created and installed and the corresponding thumbprint is added to the wif.config on the local machine\n        \n    .PARAMETER KeepCertificateFile\n        Instruct the cmdlet to copy the certificate file from the working directory into the desired location specified with OutputPath parameter\n        \n    .PARAMETER OutputPath\n        Path to where you want the certificate file exported to, when using the KeepCertificateFile parameter switch\n        \n        Default value is: \"c:\\temp\\d365fo.tools\"\n        \n    .EXAMPLE\n        PS C:\\> Initialize-D365RsatCertificate\n        \n        This will generate a certificate for issuer 127.0.0.1 and install it in the trusted root certificates and modify the wif.config of the AOS to include the thumbprint and trust the certificate.\n        \n    .EXAMPLE\n        PS C:\\> Initialize-D365RsatCertificate -CertificateOnly\n        \n        This will generate a certificate for issuer 127.0.0.1 and install it in the trusted root certificates.\n        No actions will be taken regarding modifying the AOS wif.config file.\n        \n        Use this when installing RSAT on a machine different from the AOS where RSAT is pointing to.\n        \n    .EXAMPLE\n        PS C:\\> Initialize-D365RsatCertificate -CertificateOnly -KeepCertificateFile\n        \n        This will generate a certificate for issuer 127.0.0.1 and install it in the trusted root certificates.\n        No actions will be taken regarding modifying the AOS wif.config file.\n        The pfx will be copied into the default \"c:\\temp\\d365fo.tools\" folder after creation.\n        \n        Use this when installing RSAT on a machine different from the AOS where RSAT is pointing to.\n        \n        The pfx file enables you to import the same certificate across your entire network, instead of creating one per machine.\n        \n    .NOTES\n        Tags: Automated Test, Test, Regression, Certificate, Thumbprint\n        \n        Author: Kenny Saelen (@kennysaelen)\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Initialize-D365RsatCertificate {\n    [Alias(\"Initialize-D365TestAutomationCertificate\")]\n\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidUsingConvertToSecureStringWithPlainText\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidUsingCmdletAliases\", \"\")]\n    [CmdletBinding()]\n    param (\n        [string] $CertificateFileName = (Join-Path $env:TEMP \"TestAuthCert.cer\"),\n\n        [string] $PrivateKeyFileName = (Join-Path $env:TEMP \"TestAuthCert.pfx\"),\n\n        [Security.SecureString] $Password = (ConvertTo-SecureString -String \"Password1\" -Force -AsPlainText),\n\n        [switch] $CertificateOnly,\n\n        [Parameter(ParameterSetName = \"KeepCertificateFile\")]\n        [switch] $KeepCertificateFile,\n\n        [Parameter(ParameterSetName = \"KeepCertificateFile\")]\n        [string] $OutputPath = $Script:DefaultTempPath\n    )\n\n    if (-not $Script:IsAdminRuntime) {\n        Write-PSFMessage -Level Critical -Message \"The cmdlet needs administrator permission (Run As Administrator) to be able to update the configuration. Please start an elevated session and run the cmdlet again.\"\n        Stop-PSFFunction -Message \"Elevated permissions needed. Please start an elevated session and run the cmdlet again.\"\n        return\n    }\n\n    try {\n        # Create the certificate and place it in the right stores\n        $X509Certificate = New-D365SelfSignedCertificate -CertificateFileName $CertificateFileName -PrivateKeyFileName $PrivateKeyFileName -Password $Password\n\n        if (Test-PSFFunctionInterrupt) {\n            Write-PSFMessage -Level Critical -Message \"The self signed certificate creation was interrupted.\"\n            Stop-PSFFunction -Message \"Stopping because of errors.\"\n            return\n        }\n\n        if($false -eq $CertificateOnly)\n        {\n            # Modify the wif.config of the AOS to have this thumbprint added to the https://fakeacs.accesscontrol.windows.net/ authority\n            Add-D365RsatWifConfigAuthorityThumbprint -CertificateThumbprint $X509Certificate.Thumbprint\n        }\n\n        # Write-PSFMessage -Level Host -Message \"Generated certificate: $X509Certificate\"\n\n        if($KeepCertificateFile){\n            $PrivateKeyFileName = ($PrivateKeyFileName | Copy-Item -Destination $OutputPath -PassThru).FullName\n        }\n\n        [PSCustomObject]@{\n            File = $PrivateKeyFileName\n            Filename = $(Split-Path -Path $PrivateKeyFileName -Leaf)\n        }\n\n        $X509Certificate | Format-Table Thumbprint, Subject, FriendlyName, NotAfter\n    }\n\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while configuring the certificates and the Windows Identity Foundation configuration for the AOS\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/install-d365supportingsoftware.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Install software supporting F&O development\n        \n    .DESCRIPTION\n        Installs software commonly used when doing Dynamics 365 Finance and Operations development\n        \n        Common ones: fiddler, postman, microsoft-edge, winmerge, notepadplusplus.install, azurepowershell, azure-cli, insomnia-rest-api-client, git.install\n        \n        Full list of software: https://community.chocolatey.org/packages\n        \n    .PARAMETER Name\n        The name of the software to install\n        \n        Support a list of softwares that you want to have installed on the system\n        \n    .PARAMETER Force\n        Instruct the cmdlet to install the latest version of the software, regardless if it is already present on the system\n        \n    .EXAMPLE\n        PS C:\\> Install-D365SupportingSoftware -Name vscode\n        \n        This will install VSCode on the system.\n        \n    .EXAMPLE\n        PS C:\\> Install-D365SupportingSoftware -Name \"vscode\",\"fiddler\"\n        \n        This will install VSCode and fiddler on the system.\n        \n    .EXAMPLE\n        PS C:\\> Install-D365SupportingSoftware -Name vscode -Force\n        \n        This will install VSCode on the system, forcing it to be (re)installed.\n        \n    .NOTES\n        Author: Dag Calafell (@dodiggitydag)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Install-D365SupportingSoftware {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidUsingInvokeExpression\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [Alias('SoftwareName')]\n        [string[]] $Name,\n\n        [switch] $Force\n    )\n\n    BEGIN {\n        try {\n            if (Test-Path -Path \"$env:ProgramData\\Chocolatey\") {\n                choco upgrade chocolatey -y -r\n                choco upgrade all --ignore-checksums -y -r\n            }\n            else {\n                Write-PSFMessage -Level InternalComment -Message \"Installing Chocolatey\"\n            \n                # Download and execute installation script\n                [System.Net.WebRequest]::DefaultWebProxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials\n                Invoke-Expression ((New-Object System.Net.WebClient).DownloadString(\"https://chocolatey.org/install.ps1\"))\n            }\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while installing or updating Chocolatey\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n\n        #Determine choco executable location\n        #   This is needed because the path variable is not updated in this session yet\n        #   This part is copied from https://chocolatey.org/install.ps1\n        $chocoPath = [Environment]::GetEnvironmentVariable(\"ChocolateyInstall\")\n        if ($chocoPath -eq $null -or $chocoPath -eq '') {\n            $chocoPath = \"$env:ALLUSERSPROFILE\\Chocolatey\"\n        }\n        if (!(Test-Path ($chocoPath))) {\n            $chocoPath = \"$env:SYSTEMDRIVE\\ProgramData\\Chocolatey\"\n        }\n        $chocoExePath = Join-Path $chocoPath 'bin\\choco.exe'\n\n        if (-not (Test-PathExists -Path $chocoExePath -Type Leaf)) { return }\n    }\n    \n    PROCESS {\n        if (Test-PSFFunctionInterrupt) { return }\n\n\n        \n        try {\n            foreach ($item in $Name) {\n                Write-PSFMessage -Level InternalComment -Message \"Installing $item\"\n\n                $params = New-Object System.Collections.Generic.List[System.Object]\n\n                $params.AddRange(@(\n                        \"install\"\n                        \"$item\",\n                        \"-y\",\n                        \"-r\"\n                    ))\n\n                if ($Force) {\n                    $params.Add(\"-f\")\n                }\n\n                # Use Chocolatey to install the package\n                Invoke-Process -Executable $chocoExePath -Params $($params.ToArray()) -ShowOriginalProgress:$true\n            }\n            \n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while installing software\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n    }\n    \n    END {\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365azcopytransfer.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Transfer a file using AzCopy\n        \n    .DESCRIPTION\n        Transfer a file using the AzCopy tool\n        \n        You can upload a local file to an Azure Storage Blob Container\n        \n        You can download a file located in an Azure Storage Blob Container to a local folder\n        \n        You can transfer a file located in an Azure Storage Blob Container to another Azure Storage Blob Container, across regions and subscriptions, if you have SAS tokens/keys as part of your uri\n        \n    .PARAMETER SourceUri\n        Source file uri that you want to transfer\n        \n    .PARAMETER DestinationUri\n        Destination file uri that you want to transfer the file to\n        \n    .PARAMETER FileName\n        You might only pass a blob container or folder name in the DestinationUri parameter and want to give the transfered file another name than the original file name\n        \n    .PARAMETER DeleteOnTransferComplete\n        Instruct the cmdlet to delete the source file when done transfering\n        \n        Default is $false which will leave the source file\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .PARAMETER Force\n        Instruct the cmdlet to overwrite already existing file\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365AzCopyTransfer -SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\" -DestinationUri \"c:\\temp\\d365fo.tools\\GOLDER.bacpac\"\n        \n        This will transfer a file from an Azure Storage Blob Container to a local folder/file on the machine.\n        The file that will be transfered/downloaded is SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\".\n        The file will be transfered/downloaded to DestinationUri \"c:\\temp\\d365fo.tools\\GOLDER.bacpac\".\n        \n        If there exists a file already, the file will NOT be overwritten.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365AzCopyTransfer -SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\" -DestinationUri \"c:\\temp\\d365fo.tools\\GOLDER.bacpac\" -Force\n        \n        This will transfer a file from an Azure Storage Blob Container to a local folder/file on the machine.\n        The file that will be transfered/downloaded is SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\".\n        The file will be transfered/downloaded to DestinationUri \"c:\\temp\\d365fo.tools\\GOLDER.bacpac\".\n        If there exists a file already, the file will  be overwritten, because Force has been supplied.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365AzCopyTransfer -SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\" -DestinationUri \"https://456.blob.core.windows.net/targetcontainer/filename?sv=2015-12-11&sr=...\"\n        \n        This will transfer a file from an Azure Storage Blob Container to another Azure Storage Blob Container.\n        The file that will be transfered/downloaded is SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\".\n        The file will be transfered/downloaded to DestinationUri \"https://456.blob.core.windows.net/targetcontainer/filename?sv=2015-12-11&sr=...\".\n        \n        For this to work, you need to make sure both SourceUri and DestinationUri has an valid SAS token/key included.\n        \n        If there exists a file already, the file will NOT be overwritten.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365AzCopyTransfer -SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\" -DestinationUri \"c:\\temp\\d365fo.tools\\GOLDER.bacpac\" -DeleteOnTransferComplete\n        \n        This will transfer a file from an Azure Storage Blob Container to a local folder/file on the machine.\n        The file that will be transfered/downloaded is SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\".\n        The file will be transfered/downloaded to DestinationUri \"c:\\temp\\d365fo.tools\\GOLDER.bacpac\".\n        \n        After the file has been transfered to your local \"c:\\temp\\d365fo.tools\\GOLDER.bacpac\", it will be deleted from the SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\".\n        \n    .EXAMPLE\n        PS C:\\> $DestinationParms = Get-D365AzureStorageUrl -OutputAsHashtable\n        PS C:\\> $BlobFileDetails = Get-D365LcsDatabaseBackups -Latest | Invoke-D365AzCopyTransfer @DestinationParms\n        PS C:\\> $BlobFileDetails | Invoke-D365AzCopyTransfer -DestinationUri \"C:\\Temp\" -DeleteOnTransferComplete\n        \n        This will transfer the lastest backup file from LCS Asset Library to your local \"C:\\Temp\".\n        It will get a destination Url, for it to transfer the backup file between the LCS storage account and your own.\n        The newly transfered file, that lives in your own storage account, will then be downloaded to your local \"c:\\Temp\".\n        \n        After the file has been downloaded to your local \"C:\\Temp\", it will be deleted from your own storage account.\n        \n    .NOTES\n        Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, File, Files, Latest, Bacpac, Container, LCS, Asset, Library\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages.\n        \n#>\nfunction Invoke-D365AzCopyTransfer {\n    [CmdletBinding()]\n    param (\n        [Alias('SourceUrl')]\n        [Alias('FileLocation')]\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]\n        [string] $SourceUri,\n\n        [Alias('DestinationFile')]\n        [Parameter(Mandatory = $true)]\n        [string] $DestinationUri,\n\n        [Parameter(ValueFromPipelineByPropertyName = $true)]\n        [string] $FileName,\n\n        [switch] $DeleteOnTransferComplete,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\AzCopy\"),\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly,\n\n        [switch] $Force,\n\n        [switch] $EnableException\n    )\n\n    process {\n        $executable = $Script:AzCopyPath\n\n        Invoke-TimeSignal -Start\n\n        if (-not [string]::IsNullOrEmpty($FileName)) {\n            if ($DestinationUri -like \"*?*\") {\n                $DestinationUri = $DestinationUri.Replace(\"?\", \"/$FileName`?\")\n            }\n            else {\n                if ([System.IO.File]::GetAttributes($DestinationUri).HasFlag([System.IO.FileAttributes]::Directory)) {\n                    $DestinationUri = Join-Path -Path $DestinationUri -ChildPath $FileName\n                }\n            }\n        }\n\n        $params = New-Object System.Collections.Generic.List[string]\n\n        $params.Add(\"copy\")\n        $params.Add(\"`\"$SourceUri`\"\")\n        $params.Add(\"`\"$DestinationUri`\"\")\n\n        if (-not $Force) {\n            $params.Add(\"--overwrite=false\")\n        }\n\n        Invoke-Process -Executable $executable -Params $params.ToArray() -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        if ($DeleteOnTransferComplete) {\n\n            $params = New-Object System.Collections.Generic.List[string]\n\n            $params.Add(\"remove\")\n            $params.Add(\"`\"$SourceUri`\"\")\n\n            Invoke-Process -Executable $executable -Params $params.ToArray() -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly\n        }\n\n        if ($DestinationUri -notlike \"*https*\") {\n            $filePath = Get-ChildItem -Path $DestinationUri -Recurse -File | Sort-Object CreationTime -Descending | Select-Object -First 1\n            $FileName = $filePath.Name\n        }\n        else {\n            $filePath = $DestinationUri\n        }\n\n        #Filename is missing. If Https / SAS, we need some work.\n        #If local file, it should be easy to solve\n        $res = @{\n            File       = $filePath\n            SourceUri  = $filePath\n            PSTypeName = 'D365FO.TOOLS.AZCOPYTRANSFER'\n        }\n\n        if (-not [string]::IsNullOrEmpty($FileName)) {\n            $res.FileName = $FileName\n        }\n\n        [PSCustomObject]$res\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365azuredevopsnugetpush.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Push a package / nuget to Azure DevOps\n        \n    .DESCRIPTION\n        Push a package / nuget to an Azure DevOps feed\n        \n    .PARAMETER Path\n        Path to the package / nuget that you want to push to the Azure DevOps feed\n        \n    .PARAMETER Source\n        The logical name for the nuget source / connection that you want to use while pushing the package / nuget\n        \n        This requires you to register the nuget source, by hand, using the nuget.exe tool directly\n        \n        Base command to use:\n    .\\nuget sources add -Name \"D365FO\" -Source \"https://pkgs.dev.azure.com/Contoso/DynamicsFnO/_packaging/D365Packages/NuGet/v3/index.json\" -username \"alice@contoso.dk\" -password \"uVWw43FLzaWk9H2EDguXMVYD3DaWj3aHBL6bfZkc21cmkwoK8X78\"\n        \n        Please note that the password is in fact a personal access token and NOT your real password\n        \n        The value specified for Name in the nuget sources command, is the value to supply for Source for this cmdlet\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365AzureDevOpsNugetPush -Path \"c:\\temp\\d365fo.tools\\microsoft.dynamics.ax.application.devalm.buildxpp.10.0.605.10014.nupkg\" -Source \"Contoso\"\n        \n        This will push the package / nuget to the Azure DevOps feed.\n        The file that will be pushed / uploaded is identified by the Path \"c:\\temp\\d365fo.tools\\microsoft.dynamics.ax.application.devalm.buildxpp.10.0.605.10014.nupkg\".\n        The request will be going to the Azure DevOps instance that is registered with the Source (Name) \"Contoso\" via the nuget.exe tool.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Invoke-D365AzureDevOpsNugetPush {\n    [CmdletBinding()]\n    param (\n        [Alias('PackagePath')]\n        [string] $Path,\n\n        [Alias('Destination')]\n        [Alias('NugetSource')]\n        [string] $Source,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\Nuget\"),\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly,\n\n        [switch] $EnableException\n    )\n\n    process {\n        $executable = $Script:NugetPath\n\n        $params = New-Object System.Collections.Generic.List[string]\n\n        $params.Add(\"push\")\n        $params.Add(\"`\"$Path`\"\")\n        $params.Add(\"-Source\")\n        $params.Add(\"`\"$Source`\"\")\n        $params.Add(\"-ApiKey\")\n        $params.Add(\"AzureDevOps\")\n\n        Invoke-Process -Executable $executable -Params $params.ToArray() -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365azurestoragedownload.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Download a file to Azure\n        \n    .DESCRIPTION\n        Download any file to an Azure Storage Account\n        \n    .PARAMETER AccountId\n        Storage Account Name / Storage Account Id where you want to fetch the file from\n        \n    .PARAMETER AccessToken\n        The token that has the needed permissions for the download action\n        \n    .PARAMETER SAS\n        The SAS key that you have created for the storage account or blob container\n        \n    .PARAMETER Container\n        Name of the blob container inside the storage account you where the file is\n        \n    .PARAMETER FileName\n        Name of the file that you want to download\n        \n    .PARAMETER Path\n        Path to the folder / location you want to save the file\n        \n        The default path is \"c:\\temp\\d365fo.tools\"\n        \n    .PARAMETER Latest\n        Instruct the cmdlet to download the latest file from Azure regardless of name\n        \n    .PARAMETER Force\n        Instruct the cmdlet to overwrite the local file if it already exists\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365AzureStorageDownload -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Container \"backupfiles\" -FileName \"OriginalUAT.bacpac\" -Path \"c:\\temp\"\n        \n        Will download the \"OriginalUAT.bacpac\" file from the storage account and save it to \"c:\\temp\\OriginalUAT.bacpac\"\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365AzureStorageDownload -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Container \"backupfiles\" -Path \"c:\\temp\" -Latest\n        \n        Will download the file with the latest modified datetime from the storage account and save it to \"c:\\temp\\\".\n        The complete path to the file will returned as output from the cmdlet.\n        \n    .EXAMPLE\n        PS C:\\> $AzureParams = Get-D365ActiveAzureStorageConfig\n        PS C:\\> Invoke-D365AzureStorageDownload @AzureParams -Path \"c:\\temp\" -Latest\n        \n        This will get the current Azure Storage Account configuration details\n        and use them as parameters to download the latest file from an Azure Storage Account\n        \n        Will download the file with the latest modified datetime from the storage account and save it to \"c:\\temp\\\".\n        The complete path to the file will returned as output from the cmdlet.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365AzureStorageDownload -Latest\n        \n        This will use the default parameter values that are based on the configuration stored inside \"Get-D365ActiveAzureStorageConfig\".\n        Will download the file with the latest modified datetime from the storage account and save it to \"c:\\temp\\d365fo.tools\".\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365AzureStorageDownload -AccountId \"miscfiles\" -SAS \"sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" -Container \"backupfiles\" -Path \"c:\\temp\" -Latest\n        \n        Will download the file with the latest modified datetime from the storage account and save it to \"c:\\temp\\\".\n        A SAS key is used to gain access to the container and downloading the file from it.\n        The complete path to the file will returned as output from the cmdlet.\n        \n    .NOTES\n        Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, File, Files, Latest, Bacpac, Container\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages.\n        \n#>\nfunction Invoke-D365AzureStorageDownload {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $false)]\n        [string] $AccountId = $Script:AzureStorageAccountId,\n\n        [Parameter(Mandatory = $false)]\n        [string] $AccessToken = $Script:AzureStorageAccessToken,\n\n        [Parameter(Mandatory = $false)]\n        [string] $SAS = $Script:AzureStorageSAS,\n\n        [Alias('Blob')]\n        [Alias('Blobname')]\n        [string] $Container = $Script:AzureStorageContainer,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true)]\n        [Alias('Name')]\n        [string] $FileName,\n\n        [string] $Path = $Script:DefaultTempPath,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'Latest', Position = 4 )]\n        [Alias('GetLatest')]\n        [switch] $Latest,\n\n        [switch] $Force,\n\n        [switch] $EnableException\n    )\n\n    BEGIN {\n        if (-not (Test-PathExists -Path $Path -Type Container -Create)) {\n            return\n        }\n\n        if (([string]::IsNullOrEmpty($AccountId) -eq $true) -or\n            ([string]::IsNullOrEmpty($Container)) -or\n            (([string]::IsNullOrEmpty($AccessToken)) -and ([string]::IsNullOrEmpty($SAS)))) {\n            Write-PSFMessage -Level Host -Message \"It seems that you are missing some of the parameters. Please make sure that you either supplied them or have the right configuration saved.\"\n            Stop-PSFFunction -Message \"Stopping because of missing parameters\"\n            return\n        }\n    }\n    PROCESS {\n        if (Test-PSFFunctionInterrupt) { return }\n\n        Invoke-TimeSignal -Start\n\n        try {\n\n            if ([string]::IsNullOrEmpty($SAS)) {\n                Write-PSFMessage -Level Verbose -Message \"Working against Azure Storage Account with AccessToken\"\n\n                $storageContext = New-AzStorageContext -StorageAccountName $AccountId.ToLower() -StorageAccountKey $AccessToken\n            }\n            else {\n                Write-PSFMessage -Level Verbose -Message \"Working against Azure Storage Account with SAS\"\n\n                $conString = $(\"BlobEndpoint=https://{0}.blob.core.windows.net/;QueueEndpoint=https://{0}.queue.core.windows.net/;FileEndpoint=https://{0}.file.core.windows.net/;TableEndpoint=https://{0}.table.core.windows.net/;SharedAccessSignature={1}\" -f $AccountId.ToLower(), $SAS)\n                $storageContext = New-AzStorageContext -ConnectionString $conString\n            }\n\n            Write-PSFMessage -Level Verbose -Message \"Start download from Azure Storage Account\"\n\n            if ($Latest) {\n                $files = Get-AzStorageBlob -Container $($Container.ToLower()) -Context $storageContext\n\n                $File = ($files | Sort-Object -Descending { $_.LastModified } | Select-Object -First 1)\n\n                $FileName = $File.Name\n                \n                Write-PSFMessage -Level Verbose -Message \"Filename is: $FileName\"\n\n                $NewFile = Join-Path $Path $($File.Name)\n\n                $null = Get-AzStorageBlobContent -Container $($Container.ToLower()) -Blob $File.Name -Destination $NewFile -Context $storageContext -Force:$Force\n            }\n            else {\n\n                Write-PSFMessage -Level Verbose -Message \"Filename is: $FileName\"\n\n                $NewFile = Join-Path $Path $FileName\n\n                $null = Get-AzStorageBlobContent -Container $($Container.ToLower()) -Blob $FileName -Destination $NewFile -Context $storageContext -Force:$Force\n            }\n\n            Get-Item -Path $NewFile | Select-PSFObject \"Name as Filename\", @{Name = \"Size\"; Expression = { [PSFSize]$_.Length } }, \"LastWriteTime as LastModified\", \"Fullname as File\"\n        }\n        catch {\n            $messageString = \"Something went wrong while <c='em'>downloading</c> the file from Azure.\"\n            Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target $NewFile\n            Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_\n            return\n        }\n        finally {\n            Invoke-TimeSignal -End\n        }\n    }\n\n    END { }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365azurestorageupload.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Upload a file to Azure\n        \n    .DESCRIPTION\n        Upload any file to an Azure Storage Account\n        \n    .PARAMETER AccountId\n        Storage Account Name / Storage Account Id where you want to store the file\n        \n    .PARAMETER AccessToken\n        The token that has the needed permissions for the upload action\n        \n    .PARAMETER SAS\n        The SAS key that you have created for the storage account or blob container\n        \n    .PARAMETER Container\n        Name of the blob container inside the storage account you want to store the file\n        \n    .PARAMETER Filepath\n        Path to the file you want to upload\n        \n    .PARAMETER ContentType\n        Media type of the file that is going to be uploaded\n        \n        The value will be used for the blob property \"Content Type\".\n        If the parameter is left empty, the commandlet will try to automatically determined the value based on the file's extension.\n        If the parameter is left empty and the value cannot be automatically be determined, Azure storage will automatically assign \"application/octet-stream\" as the content type.\n        Valid media type values can be found here: https://www.iana.org/assignments/media-types/media-types.xhtml\n        \n    .PARAMETER Force\n        Instruct the cmdlet to overwrite the file in the container if it already exists\n        \n    .PARAMETER DeleteOnUpload\n        Switch to tell the cmdlet if you want the local file to be deleted after the upload completes\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365AzureStorageUpload -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Container \"backupfiles\" -Filepath \"c:\\temp\\bacpac\\UAT_20180701.bacpac\" -DeleteOnUpload\n        \n        This will upload the \"c:\\temp\\bacpac\\UAT_20180701.bacpac\" up to the \"backupfiles\" container, inside the \"miscfiles\" Azure Storage Account that is access with the \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" token.\n        After upload the local file will be deleted.\n        \n    .EXAMPLE\n        PS C:\\> $AzureParams = Get-D365ActiveAzureStorageConfig\n        PS C:\\> New-D365Bacpac | Invoke-D365AzureStorageUpload @AzureParams\n        \n        This will get the current Azure Storage Account configuration details and use them as parameters to upload the file to an Azure Storage Account.\n        \n    .EXAMPLE\n        PS C:\\> New-D365Bacpac | Invoke-D365AzureStorageUpload\n        \n        This will generate a new bacpac file using the \"New-D365Bacpac\" cmdlet.\n        The file will be uploaded to an Azure Storage Account using the \"Invoke-D365AzureStorageUpload\" cmdlet.\n        This will use the default parameter values that are based on the configuration stored inside \"Get-D365ActiveAzureStorageConfig\" for the \"Invoke-D365AzureStorageUpload\" cmdlet.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365AzureStorageUpload -AccountId \"miscfiles\" -SAS \"sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" -Container \"backupfiles\" -Filepath \"c:\\temp\\bacpac\\UAT_20180701.bacpac\" -DeleteOnUpload\n        \n        This will upload the \"c:\\temp\\bacpac\\UAT_20180701.bacpac\" up to the \"backupfiles\" container, inside the \"miscfiles\" Azure Storage Account.\n        A SAS key is used to gain access to the container and uploading the file to it.\n        \n    .NOTES\n        Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, File, Files, Bacpac, Container\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages.\n        \n#>\nfunction Invoke-D365AzureStorageUpload {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $false)]\n        [string] $AccountId = $Script:AzureStorageAccountId,\n\n        [Parameter(Mandatory = $false)]\n        [string] $AccessToken = $Script:AzureStorageAccessToken,\n\n        [Parameter(Mandatory = $false)]\n        [string] $SAS = $Script:AzureStorageSAS,\n\n        [Parameter(Mandatory = $false)]\n        [Alias('Blob')]\n        [Alias('Blobname')]\n        [string] $Container = $Script:AzureStorageContainer,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', ValueFromPipeline = $true)]\n        [Parameter(Mandatory = $true, ParameterSetName = 'Pipeline', ValueFromPipelineByPropertyName = $true)]\n        [Alias('File')]\n        [Alias('Path')]\n        [string] $Filepath,\n\n        [Parameter(Mandatory = $false)]\n        [string] $ContentType,\n\n        [switch] $Force,\n\n        [switch] $DeleteOnUpload,\n\n        [switch] $EnableException\n    )\n    BEGIN {\n        if (([string]::IsNullOrEmpty($AccountId) -eq $true) -or\n            ([string]::IsNullOrEmpty($Container)) -or\n            (([string]::IsNullOrEmpty($AccessToken)) -and ([string]::IsNullOrEmpty($SAS)))) {\n            Write-PSFMessage -Level Host -Message \"It seems that you are missing some of the parameters. Please make sure that you either supplied them or have the right configuration saved.\"\n            Stop-PSFFunction -Message \"Stopping because of missing parameters\"\n            return\n        }\n    }\n    PROCESS {\n        if (Test-PSFFunctionInterrupt) { return }\n\n        Invoke-TimeSignal -Start\n\n        $FileName = Split-Path -Path $Filepath -Leaf\n        try {\n\n            if ([string]::IsNullOrEmpty($SAS)) {\n                Write-PSFMessage -Level Verbose -Message \"Working against Azure Storage Account with AccessToken\"\n\n                $storageContext = New-AzStorageContext -StorageAccountName $AccountId.ToLower() -StorageAccountKey $AccessToken\n            }\n            else {\n                $conString = $(\"BlobEndpoint=https://{0}.blob.core.windows.net/;QueueEndpoint=https://{0}.queue.core.windows.net/;FileEndpoint=https://{0}.file.core.windows.net/;TableEndpoint=https://{0}.table.core.windows.net/;SharedAccessSignature={1}\" -f $AccountId.ToLower(), $SAS)\n\n                Write-PSFMessage -Level Verbose -Message \"Working against Azure Storage Account with SAS\" -Target $conString\n                \n                $storageContext = New-AzStorageContext -ConnectionString $conString\n            }\n\n            Write-PSFMessage -Level Verbose -Message \"Start uploading the file to Azure\"\n\n            if ([string]::IsNullOrEmpty($ContentType)) {\n                $ContentType = [System.Web.MimeMapping]::GetMimeMapping($Filepath) # Available since .NET4.5, so it can be used with PowerShell 5.0 and higher.\n\n                Write-PSFMessage -Level Verbose -Message \"Content Type is automatically set to value: $ContentType\"\n            }\n\n            $null = Set-AzStorageBlobContent -Context $storageContext -File $Filepath -Container $($Container.ToLower()) -Properties @{\"ContentType\" = $ContentType} -Force:$Force\n\n            if ($DeleteOnUpload) {\n                Remove-Item $Filepath -Force\n            }\n\n            [PSCustomObject]@{\n                File     = $Filepath\n                Filename = $FileName\n            }\n        }\n        catch {\n            $messageString = \"Something went wrong while <c='em'>uploading</c> the file to Azure.\"\n            Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target $FileName\n            Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_\n            return\n        }\n        finally {\n            Invoke-TimeSignal -End\n        }\n    }\n\n    END { }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365bestpractice.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Run the Best Practice\n        \n    .DESCRIPTION\n        Run the Best Practice checks against modules and models\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the AOS service PackagesLocalDirectory\\bin\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER Module\n        Name of the Module to analyse\n        \n    .PARAMETER Model\n        Name of the Model to analyse\n        \n    .PARAMETER PackagesRoot\n        Instructs the cmdlet to use binary metadata\n        \n    .PARAMETER LogPath\n        Path where you want to store the log outputs generated from the best practice analyser\n        \n        Also used as the path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER RunFixers\n        Instructs the cmdlet to invoke the fixers for the identified warnings\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365BestPractice -module \"ApplicationSuite\" -model \"MyOverLayerModel\"\n        \n        This will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module.\n        The default output will be silenced.\n        The XML log file will be written to \"c:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.MyOverLayerModel.xppbp.xml\".\n        The log file will be written to \"c:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.MyOverLayerModel.xppbp.log\".\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365BestPractice -module \"ApplicationSuite\" -model \"MyOverLayerModel\" -PackagesRoot\n        \n        This will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module.\n        We use the binary metadata to look for the module and model.\n        The default output will be silenced.\n        The XML log file will be written to \"c:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.MyOverLayerModel.xppbp.xml\".\n        The log file will be written to \"c:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.MyOverLayerModel.xppbp.log\".\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365BestPractice -module \"ApplicationSuite\" -model \"MyOverLayerModel\" -ShowOriginalProgress\n        \n        This will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module.\n        The output from the best practice check process will be written to the console / host.\n        The XML log file will be written to \"c:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.MyOverLayerModel.xppbp.xml\".\n        The log file will be written to \"c:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.MyOverLayerModel.xppbp.log\".\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365BestPractice -module \"ApplicationSuite\" -model \"MyOverLayerModel\" -RunFixers\n        \n        This will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module.\n        The default output will be silenced.\n        The XML log file will be written to \"c:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.MyOverLayerModel.xppbp.xml\".\n        The log file will be written to \"c:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.MyOverLayerModel.xppbp.log\".\n        Instructs the xppbp tool to run the fixers for all identified warnings.\n        \n    .NOTES\n        Tags: Best Practice, BP, BPs, Module, Model, Quality\n        \n        Author: Gert Van Der Heyden (@gertvdheyden)\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Invoke-D365BestPractice {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]\n    [CmdletBinding()]\n    [OutputType('[PsCustomObject]')]\n    param (\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]\n        [Alias(\"ModuleName\")]\n        [string] $Module,\n\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]\n        [Alias('ModelName')]\n        [string] $Model,\n\n        [string] $BinDir = \"$Script:PackageDirectory\\bin\",\n\n        [string] $MetaDataDir = \"$Script:MetaDataDir\",\n\n        [switch] $PackagesRoot,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\BestPractice\"),\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $RunFixers,\n\n        [switch] $OutputCommandOnly\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n\n        $tool = \"xppbp.exe\"\n        $executable = Join-Path -Path $BinDir -ChildPath $tool\n\n        if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { return }\n        if (-not (Test-PathExists -Path $executable -Type Leaf)) { return }\n    \n    }\n    \n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n\n        $logDirModule = (Join-Path -Path $LogPath -ChildPath $Module)\n\n        if (-not (Test-PathExists -Path $logDirModule -Type Container -Create)) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        $logFile = Join-Path -Path $logDirModule -ChildPath \"Dynamics.AX.$Model.xppbp.log\"\n        $logXmlFile = Join-Path -Path $logDirModule -ChildPath \"Dynamics.AX.$Model.xppbp.xml\"\n\n        $params = @(\n            \"-metadata=`\"$MetaDataDir`\"\",\n            \"-all\",\n            \"-module=`\"$Module`\"\",\n            \"-model=`\"$Model`\"\",\n            \"-xmlLog=`\"$logXmlFile`\"\",\n            \"-log=`\"$logFile`\"\"\n        )\n\t\n        if ($PackagesRoot -eq $true) {\n            $params += \"-packagesroot=`\"$MetaDataDir`\"\"\n        }\n\n        if ($RunFixers -eq $true) {\n            $params += \"-runfixers\"\n        }\n\n        Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $logDirModule\n\n        if ($OutputCommandOnly) { return }\n        \n        [PSCustomObject]@{\n            LogFile    = $logFile\n            XmlLogFile = $logXmlFile\n        }\n    }\n\n    end {\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365compilerresultanalyzer.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Analyze the compiler output log\n        \n    .DESCRIPTION\n        Analyze the compiler output log and generate an excel file contain worksheets per type: Errors, Warnings, Tasks\n        \n        It could be a Visual Studio compiler log or it could be a Invoke-D365ModuleCompile log you want analyzed\n        \n    .PARAMETER Path\n        Path to the compiler log file that you want to work against\n        \n        A BuildModelResult.log or a Dynamics.AX.*.xppc.log file will both work\n        \n    .PARAMETER OutputPath\n        Path where you want the excel file (xlsx-file) saved to\n        \n    .PARAMETER SkipWarnings\n        Instructs the cmdlet to skip warnings while analyzing the compiler output log file\n        \n    .PARAMETER SkipTasks\n        Instructs the cmdlet to skip tasks while analyzing the compiler output log file\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Default path is the same as the AOS service \"PackagesLocalDirectory\" directory\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365CompilerResultAnalyzer -Path \"c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log\"\n        \n        This will analyse all compiler output log files generated from Visual Studio.\n        It will use the default path for the OutputPath parameter.\n        \n        It will build error and error summary worksheets.\n        It will build warning and warning summary worksheets.\n        It will build task and task summary worksheets.\n        \n        A result set example:\n        \n        File                                                            Filename\n        ----                                                            --------\n        c:\\temp\\d365fo.tools\\Custom-CompilerResults.xlsx                Custom-CompilerResults.xlsx\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365CompilerResultAnalyzer -Path \"c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log\" -SkipWarnings\n        \n        This will analyse all compiler output log files generated from Visual Studio.\n        It will use the default path for the OutputPath parameter.\n        \n        It will build error and error summary worksheets.\n        It will build task and task summary worksheets.\n        \n        A result set example:\n        \n        File                                                            Filename\n        ----                                                            --------\n        c:\\temp\\d365fo.tools\\Custom-CompilerResults.xlsx                Custom-CompilerResults.xlsx\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365CompilerResultAnalyzer -Path \"c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log\" -SkipTasks\n        \n        This will analyse all compiler output log files generated from Visual Studio.\n        It will use the default path for the OutputPath parameter.\n        \n        It will build error and error summary worksheets.\n        It will build warning and warning summary worksheets.\n        \n        A result set example:\n        \n        File                                                            Filename\n        ----                                                            --------\n        c:\\temp\\d365fo.tools\\Custom-CompilerResults.xlsx                Custom-CompilerResults.xlsx\n        \n    .NOTES\n        Tags: Compiler, Build, Errors, Warnings, Tasks\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        This cmdlet is inspired by the work of \"Vilmos Kintera\" (twitter: @DAXRunBase)\n        \n        All credits goes to him for showing how to extract these information\n        \n        His blog can be found here:\n        https://www.daxrunbase.com/blog/\n        \n        The specific blog post that we based this cmdlet on can be found here:\n        https://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/\n        \n        The github repository containing the original scrips can be found here:\n        https://github.com/DAXRunBase/PowerShell-and-Azure\n#>\nfunction Invoke-D365CompilerResultAnalyzer {\n    [CmdletBinding()]\n    [OutputType('')]\n    param (\n        [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]\n        [Alias('LogFile')]\n        [string] $Path,\n\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [switch] $SkipWarnings,\n\n        [switch] $SkipTasks,\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n\n        if (-not (Test-PathExists -Path $PackageDirectory -Type Container)) { return }\n    }\n\n    process {\n\n        $moduleName = \"\"\n\n        if($Path -like \"*Dynamics.AX.*.xppc.log\"){\n            $splittedString = $Path -split \".*Dynamics.AX.(.*).xppc.log\"\n            $moduleName = $splittedString[1]\n        }elseif ($Path -like \"*BuildModelResult.log\"){\n            $splittedString = $Path -split \".*\\\\(.*)\\\\BuildModelResult.log\"\n            $moduleName = $splittedString[1]\n        }else{\n            $moduleName = (New-Guid).Guid\n        }\n\n        $outputFilePath = Join-Path -Path $OutputPath -ChildPath \"$moduleName-CompilerResults.xlsx\"\n\n        Invoke-CompilerResultAnalyzer -Path $Path -Identifier $moduleName -OutputPath $outputFilePath -SkipWarnings:$SkipWarnings -SkipTasks:$SkipTasks -PackageDirectory $PackageDirectory\n    }\n    \n    end {\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365dataflush.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Invoke the one of the data flush classes\n        \n    .DESCRIPTION\n        Invoke one of the runnable classes that is clearing cache, data or something else\n        \n    .PARAMETER URL\n        URL to the Dynamics 365 instance you want to clear the AOD cache on\n        \n    .PARAMETER Class\n        The class that you want to execute.\n        \n        Default value is \"SysFlushAod\"\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365DataFlush\n        \n        This will make a call against the default URL for the machine and\n        have it execute the SysFlushAOD class.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365DataFlush -Class SysFlushData,SysFlushAod\n        \n        This will make a call against the default URL for the machine and\n        have it execute the SysFlushData and SysFlushAod classes.\n        \n    .NOTES\n        Tags: Flush, Url, Servicing\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Invoke-D365DataFlush {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $false, Position = 1 )]\n        [string] $Url,\n\n        [ValidateSet('SysFlushData', 'SysFlushAod', 'SysDataCacheParameters')]\n        [string[]] $Class = \"SysFlushAod\"\n    )\n\n    if ($PSBoundParameters.ContainsKey(\"URL\")) {\n        foreach ($item in $Class) {\n            Write-PSFMessage -Level Verbose -Message \"Executing Invoke-D365SysRunnerClass with $item\" -Target $item\n            Invoke-D365SysRunnerClass -ClassName $item -Url $URL\n        }\n    }\n    else {\n        foreach ($item in $Class) {\n            Write-PSFMessage -Level Verbose -Message \"Executing Invoke-D365SysRunnerClass with $item\" -Target $item\n            Invoke-D365SysRunnerClass -ClassName $item\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365dbsync.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Invoke the synchronization process used in Visual Studio\n        \n    .DESCRIPTION\n        Uses the sync.exe (engine) to synchronize the database for the environment\n        \n    .PARAMETER BinDirTools\n        Path to where the tools on the machine can be found\n        \n        Default value is normally the AOS Service PackagesLocalDirectory\\bin\n        \n    .PARAMETER MetadataDir\n        Path to where the tools on the machine can be found\n        \n        Default value is normally the AOS Service PackagesLocalDirectory\n        \n    .PARAMETER SyncMode\n        The sync mode the sync engine will use\n        \n        Default value is: \"FullAll\"\n    .PARAMETER Verbosity\n        Parameter used to instruct the level of verbosity the sync engine has to report back\n        \n        Default value is: \"Normal\"\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365DBSync\n        \n        This will invoke the sync engine and have it work against the database.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365DBSync -Verbose\n        \n        This will invoke the sync engine and have it work against the database. It will output the same level of details that Visual Studio would normally do.\n        \n    .NOTES\n        Tags: Database, Sync, SyncDB, Synchronization, Servicing\n        \n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n        When running the 'FullAll' (default) the command requires an elevated console / Run As Administrator.\n        \n#>\n\nfunction Invoke-D365DbSync {\n    [CmdletBinding()]\n    param (\n        [string] $BinDirTools = $Script:BinDirTools,\n\n        [string] $MetadataDir = $Script:MetaDataDir,\n\n        #[ValidateSet('None', 'PartialList','InitialSchema','FullIds','PreTableViewSyncActions','FullTablesAndViews','PostTableViewSyncActions','KPIs','AnalysisEnums','DropTables','FullSecurity','PartialSecurity','CleanSecurity','ADEs','FullAll','Bootstrap','LegacyIds','Diag')]\n        [string] $SyncMode = 'FullAll',\n        \n        [ValidateSet('Normal', 'Quiet', 'Minimal', 'Normal', 'Detailed', 'Diagnostic')]\n        [string] $Verbosity = 'Normal',\n\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n \n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\DbSync\"),\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly\n\n    )\n\n    Invoke-TimeSignal -Start\n\n    #! The way the sync engine works is that it uses the connection string for some operations,\n    #! but for FullSync / FullAll it depends on the database details from the same assemblies that\n    #! we rely on. So the testing of how to run this cmdlet is a bit different than others\n\n    Write-PSFMessage -Level Debug -Message \"Testing if run on LocalHostedTier1 and console isn't elevated\"\n    if ($Script:EnvironmentType -eq [EnvironmentType]::LocalHostedTier1 -and !$script:IsAdminRuntime) {\n        Write-PSFMessage -Level Host -Message \"It seems that you ran this cmdlet <c='em'>non-elevated</c> and on a <c='em'>local VM / local vhd</c>. Being on a local VM / local VHD requires you to run this cmdlet from an elevated console. Please exit the current console and start a new with `\"Run As Administrator`\"\"\n        Stop-PSFFunction -Message \"Stopping because of missing parameters\"\n        return\n    }\n    elseif (!$script:IsAdminRuntime -and $Script:UserIsAdmin -and $Script:EnvironmentType -ne [EnvironmentType]::LocalHostedTier1) {\n        Write-PSFMessage -Level Host -Message \"It seems that you ran this cmdlet <c='em'>non-elevated</c> and as an <c='em'>administrator</c>. You should either logon as a non-admin user account on this machine or run this cmdlet from an elevated console. Please exit the current console and start a new with `\"Run As Administrator`\" or simply logon as another user\"\n        Stop-PSFFunction -Message \"Stopping because of missing parameters\"\n        return\n    }\n\n    $executable = Join-Path -Path $BinDirTools -ChildPath \"SyncEngine.exe\"\n    if (-not (Test-PathExists -Path $executable -Type Leaf)) { return }\n    if (-not (Test-PathExists -Path $MetadataDir -Type Container)) { return }\n\n    Write-PSFMessage -Level Debug -Message \"Testing if the SyncEngine is already running.\"\n    $syncEngine = Get-Process -Name \"SyncEngine\" -ErrorAction SilentlyContinue\n    \n    if ($null -ne $syncEngine) {\n        Write-PSFMessage -Level Host -Message \"A instance of SyncEngine is <c='em'>already running</c>. Please <c='em'>wait</c> for it to finish or <c='em'>kill it</c>.\"\n        Stop-PSFFunction -Message \"Stopping because SyncEngine.exe already running\"\n        return\n    }\n    \n    Write-PSFMessage -Level Debug -Message \"Build the parameters for the command to execute.\"\n    $params = @(\"-syncmode=$($SyncMode.ToLower())\",\n        \"-verbosity=$($Verbosity.ToLower())\",\n        \"-metadatabinaries=`\"$MetadataDir`\"\",\n        \"-connect=`\"server=$DatabaseServer;Database=$DatabaseName; User Id=$SqlUser;Password='$SqlPwd';`\"\"\n    )\n\n    Write-PSFMessage -Level Debug -Message \"Starting the SyncEngine with the parameters.\" -Target $param\n    #! We should consider to redirect the standard output & error like this: https://stackoverflow.com/questions/8761888/capturing-standard-out-and-error-with-start-process\n    Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n    \n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365dbsyncmodule.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Synchronize all sync base and extension elements based on a modulename\n        \n    .DESCRIPTION\n        Retrieve the list of installed packages / modules where the name fits the ModelName parameter.\n        \n        It will run loop over the list and start the sync process against all tables, views, data entities, table-extensions,\n        view-extensions and data entities-extensions of every iterated model\n        \n    .PARAMETER Module\n        Name of the model you want to sync tables and table extensions\n        \n        Supports an array of module names\n        \n    .PARAMETER LogPath\n        The path where the log file will be saved\n        \n    .PARAMETER Verbosity\n        Parameter used to instruct the level of verbosity the sync engine has to report back\n        \n        Default value is: \"Normal\"\n        \n    .PARAMETER BinDirTools\n        Path to where the tools on the machine can be found\n        \n        Default value is normally the AOS Service PackagesLocalDirectory\\bin\n        \n    .PARAMETER MetadataDir\n        Path to where the tools on the machine can be found\n        \n        Default value is normally the AOS Service PackagesLocalDirectory\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365DbSyncModule -Module \"MyModel1\"\n        \n        It will start the sync process against all tables, views, data entities, table-extensions, view-extensions and data entities-extensions of MyModel1.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365DbSyncModule -Module \"MyModel1\",\"MyModel2\"\n        \n        It will run loop over the list and start the sync process against all tables, views, data entities, table-extensions, view-extensions and data entities-extensions of every iterated model.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Module -Name \"MyModel*\" | Invoke-D365DbSyncModule\n        \n        Retrieve the list of installed packages / modules where the name fits the search \"MyModel*\".\n        \n        The result is:\n        MyModel1\n        MyModel2\n        \n        It will run loop over the list and start the sync process against all tables, views, data entities, table-extensions, view-extensions and data entities-extensions of every iterated model.\n        \n    .NOTES\n        Tags: Database, Sync, SyncDB, Synchronization, Servicing\n        \n        Author: Jasper Callens - Cegeka\n        \n        Author: Caleb Blanchard (@daxcaleb)\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Invoke-D365DbSyncModule {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]\n        [Alias(\"ModuleName\")]\n        [string[]] $Module,\n\n        [ValidateSet('Normal', 'Quiet', 'Minimal', 'Normal', 'Detailed', 'Diagnostic')]\n        [string] $Verbosity = 'Normal',\n\n        [string] $BinDirTools = $Script:BinDirTools,\n\n        [string] $MetadataDir = $Script:MetaDataDir,\n\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\DbSync\"),\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n\n        [System.Collections.Generic.List[System.String]] $modules = @()\n    }\n\n    process {\n        foreach ($moduleLocal in $Module) {\n            $modules.Add($moduleLocal)\n        }\n    }\n\n    end {\n        # Retrieve all sync elements of provided module name\n        $allModelSyncElements = $modules.ToArray() | Get-SyncElements\n\n        # Build parameters for the partial sync function\n        $syncParams = @{\n            SyncList             = $allModelSyncElements.BaseSyncElements;\n            SyncExtensionsList   = $allModelSyncElements.ExtensionSyncElements;\n            Verbosity            = $Verbosity;\n            BinDirTools          = $BinDirTools;\n            MetadataDir          = $MetadataDir;\n            DatabaseServer       = $DatabaseServer;\n            DatabaseName         = $DatabaseName;\n            SqlUser              = $SqlUser;\n            SqlPwd               = $SqlPwd;\n            LogPath              = $LogPath;\n            ShowOriginalProgress = $ShowOriginalProgress;\n            OutputCommandOnly    = $OutputCommandOnly;\n        }\n\n        # Call the partial sync using required parameters\n        $resSyncModule = Invoke-D365DBSyncPartial @syncParams\n\n        $resSyncModule\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365dbsyncpartial.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Invoke the synchronization process used in Visual Studio\n        \n    .DESCRIPTION\n        Uses the sync.exe (engine) to synchronize the database for the environment\n        \n    .PARAMETER SyncMode\n        The sync mode the sync engine will use\n        \n        Default value is: \"PartialList\"\n        \n    .PARAMETER SyncList\n        The list of objects that you want to pass on to the database synchronoziation engine\n        \n    .PARAMETER SyncExtensionsList\n        The list of extension objects that you want to pass on to the database synchronoziation engine\n        \n    .PARAMETER Verbosity\n        Parameter used to instruct the level of verbosity the sync engine has to report back\n        \n        Default value is: \"Normal\"\n        \n    .PARAMETER BinDirTools\n        Path to where the tools on the machine can be found\n        \n        Default value is normally the AOS Service PackagesLocalDirectory\\bin\n        \n    .PARAMETER MetadataDir\n        Path to where the tools on the machine can be found\n        \n        Default value is normally the AOS Service PackagesLocalDirectory\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365DBSyncPartial -SyncList \"CustCustomerEntity\",\"SalesTable\"\n        \n        This will invoke the sync engine and have it work against the database.\n        It will run with the default value \"PartialList\" as the SyncMode.\n        It will run the sync process against \"CustCustomerEntity\" and \"SalesTable\"\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365DBSyncPartial -SyncList \"CustCustomerEntity\",\"SalesTable\" -Verbose\n        \n        This will invoke the sync engine and have it work against the database.\n        It will run with the default value \"PartialList\" as the SyncMode.\n        It will run the sync process against \"CustCustomerEntity\" and \"SalesTable\"\n        \n        It will output the same level of details that Visual Studio would normally do.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365DBSyncPartial -SyncList \"CustCustomerEntity\",\"SalesTable\" -SyncExtensionsList \"CaseLog.Extension\",\"CategoryTable.Extension\" -Verbose\n        \n        This will invoke the sync engine and have it work against the database.\n        It will run with the default value \"PartialList\" as the SyncMode.\n        It will run the sync process against \"CustCustomerEntity\", \"SalesTable\", \"CaseLog.Extension\" and \"CategoryTable.Extension\"\n        \n        It will output the same level of details that Visual Studio would normally do.\n        \n    .NOTES\n        Tags: Database, Sync, SyncDB, Synchronization, Servicing\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        Author: Jasper Callens - Cegeka\n        \n        Inspired by:\n        https://axdynamx.blogspot.com/2017/10/how-to-synchronize-manually-database.html\n        \n#>\n\nfunction Invoke-D365DbSyncPartial {\n    [CmdletBinding()]\n    param (\n        [string[]] $SyncList,\n\n        [string[]] $SyncExtensionsList,\n\n        #[ValidateSet('None', 'PartialList','InitialSchema','FullIds','PreTableViewSyncActions','FullTablesAndViews','PostTableViewSyncActions','KPIs','AnalysisEnums','DropTables','FullSecurity','PartialSecurity','CleanSecurity','ADEs','FullAll','Bootstrap','LegacyIds','Diag')]\n        [string] $SyncMode = 'PartialList',\n\n        [ValidateSet('Normal', 'Quiet', 'Minimal', 'Normal', 'Detailed', 'Diagnostic')]\n        [string] $Verbosity = 'Normal',\n\n        [string] $BinDirTools = $Script:BinDirTools,\n\n        [string] $MetadataDir = $Script:MetaDataDir,\n\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\DbSync\"),\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly\n    )\n\n    process {\n        Invoke-TimeSignal -Start\n        \n        #! The way the sync engine works is that it uses the connection string for some operations,\n        #! but for FullSync / FullAll it depends on the database details from the same assemblies that\n        #! we rely on. So the testing of how to run this cmdlet is a bit different than others\n\n        Write-PSFMessage -Level Debug -Message \"Testing if run on LocalHostedTier1 and console isn't elevated\"\n        if ($Script:EnvironmentType -eq [EnvironmentType]::LocalHostedTier1 -and !$script:IsAdminRuntime) {\n            Write-PSFMessage -Level Host -Message \"It seems that you ran this cmdlet <c='em'>non-elevated</c> and on a <c='em'>local VM / local vhd</c>. Being on a local VM / local VHD requires you to run this cmdlet from an elevated console. Please exit the current console and start a new with `\"Run As Administrator`\"\"\n            Stop-PSFFunction -Message \"Stopping because of missing parameters\"\n            return\n        }\n        elseif (!$script:IsAdminRuntime -and $Script:UserIsAdmin -and $Script:EnvironmentType -ne [EnvironmentType]::LocalHostedTier1) {\n            Write-PSFMessage -Level Host -Message \"It seems that you ran this cmdlet <c='em'>non-elevated</c> and as an <c='em'>administrator</c>. You should either logon as a non-admin user account on this machine or run this cmdlet from an elevated console. Please exit the current console and start a new with `\"Run As Administrator`\" or simply logon as another user\"\n            Stop-PSFFunction -Message \"Stopping because of missing parameters\"\n            return\n        }\n\n        $executable = Join-Path -Path $BinDirTools -ChildPath \"SyncEngine.exe\"\n        if (-not (Test-PathExists -Path $executable -Type Leaf)) { return }\n        if (-not (Test-PathExists -Path $MetadataDir -Type Container)) { return }\n\n        Write-PSFMessage -Level Debug -Message \"Testing if the SyncEngine is already running.\"\n        $syncEngine = Get-Process -Name \"SyncEngine\" -ErrorAction SilentlyContinue\n        \n        if ($null -ne $syncEngine) {\n            Write-PSFMessage -Level Host -Message \"A instance of SyncEngine is <c='em'>already running</c>. Please <c='em'>wait</c> for it to finish or <c='em'>kill it</c>.\"\n            Stop-PSFFunction -Message \"Stopping because SyncEngine.exe already running\"\n            return\n        }\n        \n        Write-PSFMessage -Level Debug -Message \"Build the parameters for the command to execute.\"\n        $params = @(\"-syncmode=$($SyncMode.ToLower())\",\n            \"-synclist=`\"$($SyncList -join \",\")`\"\",\n            \"-tableextensionlist=`\"$($SyncExtensionsList -join ',')`\"\",\n            \"-verbosity=$($Verbosity.ToLower())\",\n            \"-metadatabinaries=`\"$MetadataDir`\"\",\n            \"-connect=`\"server=$DatabaseServer;Database=$DatabaseName; User Id=$SqlUser;Password=$SqlPwd;`\"\"\n        )\n\n        Write-PSFMessage -Level Debug -Message \"Starting the SyncEngine with the parameters.\" -Target $param\n        #! We should consider to redirect the standard output & error like this: https://stackoverflow.com/questions/8761888/capturing-standard-out-and-error-with-start-process\n        Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n        \n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365generatereportaggregatedataentity.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate Report for Aggregate Data Entity\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all Aggregate Data Entities and generate a metadata report\n        \n    .PARAMETER OutputPath\n        Path to where you want the report file to be saved\n        \n        The default value is: \"c:\\temp\\d365fo.tools\\\"\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365GenerateReportAggregateDataEntity\n        \n        This will generate a report.\n        It will contain all the metadata and save it into a xlsx (Excel) file.\n        It will saved the file to \"c:\\temp\\d365fo.tools\\\"\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nfunction Invoke-D365GenerateReportAggregateDataEntity {\n    [CmdletBinding()]\n    param (\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    begin {\n        $outputFile = Join-Path -Path $OutputPath -ChildPath \"AggregateDataEntities.xlsx\"\n\n        Import-GenerateReportAssemblies\n\n        $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n        $providerConfig.XppMetadataPath = $PackageDirectory\n        $providerConfig.MetadataPath = $PackageDirectory\n\n        $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig)\n\n        $productVersionDetails = Get-D365ProductInformation\n        \n        if (-not $productVersionDetails.ApplicationBuildVersion) {\n            $version = $productVersionDetails.ApplicationVersion\n        }\n        else {\n            $version = $productVersionDetails.ApplicationBuildVersion\n        }\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        Write-PSFMessage -Level Verbose -Message \"Getting all Aggregate Data Entities via the metadata provider.\"\n        $aggregateDataEntityModelInfos = $metadataProvider.AggregateDataEntities.GetPrimaryKeysWithModelInfo()\n\n        $aggregateDataEntities = New-Object System.Collections.Generic.List[object]\n\n        foreach ($tuple in $aggregateDataEntityModelInfos) {\n            $elementName = $tuple.Item1\n\n            Write-PSFMessage -Level Verbose -Message \"Working on: $elementName (AggregateDataEntity)\" -Target $elementName\n\n            $modelInfoNames = $tuple.Item2 | Select-Object -ExpandProperty Name # convert list of ModelInfo objects to list of Names\n            $modelNames = [string]::Join(\"; \", $modelInfoNames);\n\n            $element = $metadataProvider.AggregateDataEntities.Read($elementName)\n\n            #filter out system fields\n            $fields = @()\n            foreach ($j in $element.Fields) {\n                if ($j -notlike \"AX_*\") {\n                    $fields += $j\n                }\n            }\n\n            $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair\n                Name                 = $element.Name\n                DataSource           = $element.AggregateViewDataSource.Measurement\n                Public               = $element.IsPublic\n                PublicCollectionName = $element.PublicCollectionName\n                TableGroup           = $element.TableGroup\n                EntityCategory       = $element.EntityCategory\n                Fields               = [string]::Join(\", \", $fields)\n                Models               = $modelNames\n            }\n\n            $aggregateDataEntities.Add($outItems)\n        }\n\n        $reportName = \"AggregateDataEntities\"\n        $sheetName = \"$reportName`_$version\"\n        $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length))\n\n        $aggregateDataEntities | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName\n\n        [PSCustomObject]@{\n            Report = $reportName\n            File     = $outputFile\n            Filename = (Split-Path $outputFile -Leaf)\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365generatereportaggregatemeasure.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate Report for Aggregate Measure\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all Aggregate Measures and generate a metadata report\n        \n    .PARAMETER OutputPath\n        Path to where you want the report file to be saved\n        \n        The default value is: \"c:\\temp\\d365fo.tools\\\"\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365GenerateReportAggregateMeasure\n        \n        This will generate a report.\n        It will contain all the metadata and save it into a xlsx (Excel) file.\n        It will saved the file to \"c:\\temp\\d365fo.tools\\\"\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nfunction Invoke-D365GenerateReportAggregateMeasure {\n    [CmdletBinding()]\n    param (\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    begin {\n        $outputFile = Join-Path -Path $OutputPath -ChildPath \"AggregateMeasures.xlsx\"\n\n        Write-PSFMessage -Level Verbose -Message \"Getting all Aggregate Measures from the internal functions.\"\n        $aggregateMeasures = Get-AxAggregateMeasures -BinDir $BinDir -PackageDirectory $PackageDirectory\n\n        $productVersionDetails = Get-D365ProductInformation\n        \n        if (-not $productVersionDetails.ApplicationBuildVersion) {\n            $version = $productVersionDetails.ApplicationVersion\n        }\n        else {\n            $version = $productVersionDetails.ApplicationBuildVersion\n        }\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        $reportName = \"AggregateMeasures\"\n        $sheetName = \"$reportName`_$version\"\n        $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length))\n\n        $aggregateMeasures | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName\n        \n        [PSCustomObject]@{\n            Report = $reportName\n            File     = $outputFile\n            Filename = (Split-Path $outputFile -Leaf)\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365generatereportconfigkey.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate Report for Config Key\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all Config Keys and generate a metadata report\n        \n    .PARAMETER OutputPath\n        Path to where you want the report file to be saved\n        \n        The default value is: \"c:\\temp\\d365fo.tools\\\"\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365GenerateReportConfigKey\n        \n        This will generate a report.\n        It will contain all the metadata and save it into a xlsx (Excel) file.\n        It will saved the file to \"c:\\temp\\d365fo.tools\\\"\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nfunction Invoke-D365GenerateReportConfigKey {\n    [CmdletBinding()]\n    param (\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    begin {\n        $outputFile = Join-Path -Path $OutputPath -ChildPath \"ConfigKeys.xlsx\"\n\n        Import-GenerateReportAssemblies\n\n        $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n        $providerConfig.XppMetadataPath = $PackageDirectory\n        $providerConfig.MetadataPath = $PackageDirectory\n\n        $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig)\n\n        $productVersionDetails = Get-D365ProductInformation\n        \n        if (-not $productVersionDetails.ApplicationBuildVersion) {\n            $version = $productVersionDetails.ApplicationVersion\n        }\n        else {\n            $version = $productVersionDetails.ApplicationBuildVersion\n        }\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        Write-PSFMessage -Level Verbose -Message \"Getting all Configuration Keys via the metadata provider.\"\n        $configKeyModelInfos = $metadataProvider.ConfigurationKeys.GetPrimaryKeysWithModelInfo()\n\n        $configKeys = New-Object System.Collections.Generic.List[object]\n\n        foreach ($tuple in $configKeyModelInfos) {\n            $elementName = $tuple.Item1\n\n            Write-PSFMessage -Level Verbose -Message \"Working on: $elementName (ConfigurationKey)\" -Target $elementName\n\n            $modelInfoNames = $tuple.Item2 | Select-Object -ExpandProperty Name # convert list of ModelInfo objects to list of Names\n            $modelNames = [string]::Join(\"; \", $modelInfoNames);\n\n            $element = $metadataProvider.ConfigurationKeys.Read($elementName)\n\n            $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair\n                Name        = $element.Name\n                Models      = $modelNames\n                LicenseCode = $element.LicenseCode\n                ParentKey   = $element.ParentKey\n                ConfigKey   = $element.ConfigurationKey\n                Enabled     = $element.Enabled\n                LabelID     = $element.Label\n                Label       = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.Label)\n            }\n\n            $configKeys.Add($outItems)\n        }\n        \n        $reportName = \"ConfigKeys\"\n        $sheetName = \"$reportName`_$version\"\n        $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length))\n\n        $configKeys | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName\n\n        [PSCustomObject]@{\n            Report = $reportName\n            File     = $outputFile\n            Filename = (Split-Path $outputFile -Leaf)\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365generatereportconfigkeygroup.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate Report for Config Key Group\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all Config Key Groups and generate a metadata report\n        \n    .PARAMETER OutputPath\n        Path to where you want the report file to be saved\n        \n        The default value is: \"c:\\temp\\d365fo.tools\\\"\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365GenerateReportConfigKeyGroup\n        \n        This will generate a report.\n        It will contain all the metadata and save it into a xlsx (Excel) file.\n        It will saved the file to \"c:\\temp\\d365fo.tools\\\"\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nfunction Invoke-D365GenerateReportConfigKeyGroup {\n    [CmdletBinding()]\n    param (\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    begin {\n        $outputFile = Join-Path -Path $OutputPath -ChildPath \"ConfigKeyGroups.xlsx\"\n\n        Import-GenerateReportAssemblies\n\n        $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n        $providerConfig.XppMetadataPath = $PackageDirectory\n        $providerConfig.MetadataPath = $PackageDirectory\n\n        $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig)\n\n        $productVersionDetails = Get-D365ProductInformation\n        \n        if (-not $productVersionDetails.ApplicationBuildVersion) {\n            $version = $productVersionDetails.ApplicationVersion\n        }\n        else {\n            $version = $productVersionDetails.ApplicationBuildVersion\n        }\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        Write-PSFMessage -Level Verbose -Message \"Getting all Configuration Key Groups via the metadata provider.\"\n        $configKeyModelInfos = $metadataProvider.ConfigurationKeyGroups.GetPrimaryKeysWithModelInfo()\n\n        $configKeyGroups = New-Object System.Collections.Generic.List[object]\n\n        foreach ($tuple in $configKeyModelInfos) {\n            $elementName = $tuple.Item1\n            \n            Write-PSFMessage -Level Verbose -Message \"Working on: $elementName (ConfigurationKeyGroup)\" -Target $elementName\n\n            $modelInfoNames = $tuple.Item2 | Select-Object -ExpandProperty Name # convert list of ModelInfo objects to list of Names\n            $modelNames = [string]::Join(\"; \", $modelInfoNames);\n\n            $element = $metadataProvider.ConfigurationKeyGroups.Read($elementName)\n\n            $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair\n                Name           = $element.Name\n                Models         = $modelNames\n                LicenseCode    = $element.LicenseCode\n                ParentKeyGroup = $element.ParentKeyGroup\n                ConfigKeys     = $element.ConfigurationKeys\n                Enabled        = $element.Enabled\n                LabelID        = $element.Label\n                Label          = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.Label)\n            }\n\n            $configKeyGroups.Add($outItems)\n        }\n        \n        $reportName = \"ConfigKeyGroups\"\n        $sheetName = \"$reportName`_$version\"\n        $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length))\n\n        $configKeyGroups | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName\n\n        [PSCustomObject]@{\n            Report = $reportName\n            File     = $outputFile\n            Filename = (Split-Path $outputFile -Leaf)\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365generatereportdataentity.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate Report for Data Entity\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all Data Entities and generate a metadata report\n        \n    .PARAMETER OutputPath\n        Path to where you want the report file to be saved\n        \n        The default value is: \"c:\\temp\\d365fo.tools\\\"\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365GenerateReportDataEntity\n        \n        This will generate a report.\n        It will contain all the metadata and save it into a xlsx (Excel) file.\n        It will saved the file to \"c:\\temp\\d365fo.tools\\\"\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nfunction Invoke-D365GenerateReportDataEntity {\n    [CmdletBinding()]\n    param (\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    begin {\n        $outputFile = Join-Path -Path $OutputPath -ChildPath \"DataEntities.xlsx\"\n\n        Import-GenerateReportAssemblies\n\n        $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n        $providerConfig.XppMetadataPath = $PackageDirectory\n        $providerConfig.MetadataPath = $PackageDirectory\n\n        $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig)\n\n        $productVersionDetails = Get-D365ProductInformation\n        \n        if (-not $productVersionDetails.ApplicationBuildVersion) {\n            $version = $productVersionDetails.ApplicationVersion\n        }\n        else {\n            $version = $productVersionDetails.ApplicationBuildVersion\n        }\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        Write-PSFMessage -Level Verbose -Message \"Getting all Data Entities via the metadata provider.\"\n        $dataEntityModelInfos = $metadataProvider.DataEntityViews.GetPrimaryKeysWithModelInfo()\n\n        $dataEntities = New-Object System.Collections.Generic.List[object]\n        \n        foreach ($tuple in $dataEntityModelInfos) {\n            $elementName = $tuple.Item1\n\n            Write-PSFMessage -Level Verbose -Message \"Working on: $elementName (DataEntity)\" -Target $elementName\n            \n            $element = $metadataProvider.DataEntityViews.Read($elementName)\n\n            #filter out system fields\n            $fields = @()\n            foreach ($j in $element.Fields) {\n                if ($j -notlike \"AX_*\") {\n                    $fields += $j\n                }\n            }\n\n            $outItems = [PsCustomObject][ordered] @{ # create a hash table of the name/value pair\n                Name                  = $element.Name\n                DataSource            = [string]::Join(\", \", $element.ViewMetadata.DataSources)\n                Public                = $element.IsPublic\n                ODataAccessible       = $element.IsPublic\n                PublicCollectionName  = $element.PublicCollectionName\n                StagingTable          = $element.DataManagementStagingTable\n                EntityCategory        = $element.EntityCategory\n                TableGroup            = $element.TableGroup\n                Fields                = [string]::Join(\", \", $fields)\n                DataManagementEnabled = $element.DataManagementEnabled\n            }\n\n            $dataEntities.add($outItems)\n        }\n\n        $reportName = \"DataEntities\"\n        $sheetName = \"$reportName`_$version\"\n        $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length))\n\n        $dataEntities | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName\n\n        [PSCustomObject]@{\n            Report   = $reportName\n            File     = $outputFile\n            Filename = (Split-Path $outputFile -Leaf)\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365generatereportdataentityfield.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate Report for Data Entity with fields\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all Data Entities with their fields and generate a metadata report\n        \n    .PARAMETER OutputPath\n        Path to where you want the report file to be saved\n        \n        The default value is: \"c:\\temp\\d365fo.tools\\\"\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365GenerateReportDataEntityField\n        \n        This will generate a report.\n        It will contain all the metadata and save it into a xlsx (Excel) file.\n        It will saved the file to \"c:\\temp\\d365fo.tools\\\"\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nfunction Invoke-D365GenerateReportDataEntityField {\n    [CmdletBinding()]\n    param (\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    begin {\n        $outputFile = Join-Path -Path $OutputPath -ChildPath \"DataEntityFields.xlsx\"\n        \n        Write-PSFMessage -Level Verbose -Message \"Getting all Data Entities with Fields from the internal functions.\"\n        $dataEntities = Get-AxDataEntities -BinDir $BinDir -PackageDirectory $PackageDirectory\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n\n        $reportName = \"DataEntityFields\"\n        $sheetName = \"$reportName`_$version\"\n        $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length))\n\n        $dataEntities | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName\n\n        [PSCustomObject]@{\n            Report = $reportName\n            File     = $outputFile\n            Filename = (Split-Path $outputFile -Leaf)\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365generatereportkpi.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate Report for KPI\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all KPIs and generate a metadata report\n        \n    .PARAMETER OutputPath\n        Path to where you want the report file to be saved\n        \n        The default value is: \"c:\\temp\\d365fo.tools\\\"\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365GenerateReportKpi\n        \n        This will generate a report.\n        It will contain all the metadata and save it into a xlsx (Excel) file.\n        It will saved the file to \"c:\\temp\\d365fo.tools\\\"\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nfunction Invoke-D365GenerateReportKpi {\n    [CmdletBinding()]\n    param (\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    begin {\n        $outputFile = Join-Path -Path $OutputPath -ChildPath \"KPIs.xlsx\"\n\n        Import-GenerateReportAssemblies\n\n        $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n        $providerConfig.XppMetadataPath = $PackageDirectory\n        $providerConfig.MetadataPath = $PackageDirectory\n\n        $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig)\n\n        $productVersionDetails = Get-D365ProductInformation\n        \n        if (-not $productVersionDetails.ApplicationBuildVersion) {\n            $version = $productVersionDetails.ApplicationVersion\n        }\n        else {\n            $version = $productVersionDetails.ApplicationBuildVersion\n        }\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        Write-PSFMessage -Level Verbose -Message \"Getting all KPIs via the metadata provider.\"\n        $KPIModelInfos = $metadataProvider.KPIs.GetPrimaryKeysWithModelInfo()\n\n        $KPIs = New-Object System.Collections.Generic.List[object]\n\n        foreach ($tuple in $KPIModelInfos) {\n            $elementName = $tuple.Item1\n    \n            Write-PSFMessage -Level Verbose -Message \"Working on: $elementName (KPI)\" -Target $elementName\n            \n            $element = $metadataProvider.KPIs.Read($elementName)\n    \n            if ($element.Name -eq \"FMRevenue\") {\n                $calcMeasure = $element.Value.Measure\n                $calcMeasureGroup = $element.Value.MeasureGroup\n            }\n            else {\n                $calcMeasure = $element.Goal.Measure\n                $calcMeasureGroup = $element.Goal.MeasureGroup\n            }\n    \n            $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair\n                Name                   = $element.Name\n                Label                  = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.Label)\n                Measurement            = $element.Measurement\n                ValueType              = $element.Value.ValueType\n                GoalType               = $element.Goal.GoalType\n                Value                  = $element.goal.Value\n                CalculatedMeasure      = $calcMeasure\n                CalculatedMeasureGroup = $calcMeasureGroup\n                FormExposed            = \"\"\n                WorkspaceExposed       = \"\"\n            }\n    \n            $KPIs.Add($outItems)\n        }\n        \n        $reportName = \"KPIs\"\n        $sheetName = \"$reportName`_$version\"\n        $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length))\n\n        $KPIs | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName\n\n        [PSCustomObject]@{\n            Report = $reportName\n            File     = $outputFile\n            Filename = (Split-Path $outputFile -Leaf)\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365generatereportlicensecode.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate Report for License Code\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all License Codes and generate a metadata report\n        \n    .PARAMETER OutputPath\n        Path to where you want the report file to be saved\n        \n        The default value is: \"c:\\temp\\d365fo.tools\\\"\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365GenerateReportLicenseCode\n        \n        This will generate a report.\n        It will contain all the metadata and save it into a xlsx (Excel) file.\n        It will saved the file to \"c:\\temp\\d365fo.tools\\\"\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nfunction Invoke-D365GenerateReportLicenseCode {\n    [CmdletBinding()]\n    param (\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    begin {\n        $outputFile = Join-Path -Path $OutputPath -ChildPath \"LicenseCodes.xlsx\"\n\n        Import-GenerateReportAssemblies\n\n        $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n        $providerConfig.XppMetadataPath = $PackageDirectory\n        $providerConfig.MetadataPath = $PackageDirectory\n\n        $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig)\n\n        $productVersionDetails = Get-D365ProductInformation\n        \n        if (-not $productVersionDetails.ApplicationBuildVersion) {\n            $version = $productVersionDetails.ApplicationVersion\n        }\n        else {\n            $version = $productVersionDetails.ApplicationBuildVersion\n        }\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        Write-PSFMessage -Level Verbose -Message \"Getting all License Codes via the metadata provider.\"\n        $licenseCodeModelInfos = $metadataProvider.LicenseCodes.GetPrimaryKeysWithModelInfo()\n\n        $licenseCodes = New-Object System.Collections.Generic.List[object]\n\n        foreach ($tuple in $licenseCodeModelInfos) {\n            $elementName = $tuple.Item1\n\n            Write-PSFMessage -Level Verbose -Message \"Working on: $elementName (LicenseCode)\" -Target $elementName\n\n            $modelInfoNames = $tuple.Item2 | Select-Object -ExpandProperty Name # convert list of ModelInfo objects to list of Names\n            $modelNames = [string]::Join(\"; \", $modelInfoNames);\n\n            $element = $metadataProvider.LicenseCodes.Read($elementName)\n\n            $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair\n                Name    = $element.Name\n                Models  = $modelNames\n                Package = $element.Package\n                LabelID = $element.Label\n                Label   = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.Label)\n            }\n\n            $licenseCodes.Add($outItems)\n        }\n        \n        $reportName = \"LicenseCodes\"\n        $sheetName = \"$reportName`_$version\"\n        $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length))\n\n        $licenseCodes | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName\n\n        [PSCustomObject]@{\n            Report = $reportName\n            File     = $outputFile\n            Filename = (Split-Path $outputFile -Leaf)\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365generatereportmenuitem.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate Report for Menu Item\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all types of Menu Items and generate a metadata report\n        \n    .PARAMETER OutputPath\n        Path to where you want the report file to be saved\n        \n        The default value is: \"c:\\temp\\d365fo.tools\\\"\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365GenerateReportMenuItem\n        \n        This will generate a report.\n        It will contain all the metadata and save it into a xlsx (Excel) file.\n        It will saved the file to \"c:\\temp\\d365fo.tools\\\"\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nfunction Invoke-D365GenerateReportMenuItem {\n    [CmdletBinding()]\n    param (\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    begin {\n        $outputFile = Join-Path -Path $OutputPath -ChildPath \"MenuItems.xlsx\"\n\n        Import-GenerateReportAssemblies\n\n        $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n        $providerConfig.XppMetadataPath = $PackageDirectory\n        $providerConfig.MetadataPath = $PackageDirectory\n\n        $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig)\n\n        $productVersionDetails = Get-D365ProductInformation\n        \n        if (-not $productVersionDetails.ApplicationBuildVersion) {\n            $version = $productVersionDetails.ApplicationVersion\n        }\n        else {\n            $version = $productVersionDetails.ApplicationBuildVersion\n        }\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        Write-PSFMessage -Level Verbose -Message \"Getting all Menu Items (Display) via the metadata provider.\"\n        $displayMenuItemModelInfos = $metadataProvider.MenuItemDisplays.GetPrimaryKeysWithModelInfo()\n\n        $menuItems = New-Object System.Collections.Generic.List[object]\n\n        foreach ($tuple in $displayMenuItemModelInfos) {\n            $elementName = $tuple.Item1\n\n            Write-PSFMessage -Level Verbose -Message \"Working on: $elementName (MenuItemDisplay)\" -Target $elementName\n\n            $modelInfoNames = $tuple.Item2 | Select-Object -ExpandProperty Name # convert list of ModelInfo objects to list of Names\n            $modelNames = [string]::Join(\"; \", $modelInfoNames);\n\n            $element = $metadataProvider.MenuItemDisplays.Read($elementName)\n\n            $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair\n                Name         = $element.Name\n                MenuItemType = \"Display\"\n                Models       = $modelNames\n                ObjectType   = $element.ObjectType\n                Object       = $element.Object\n                ConfigKey    = $element.ConfigurationKey\n                Enabled      = $element.Enabled\n                LabelID      = $element.Label\n                Label        = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.Label)\n            }\n\n            $menuItems.Add($outItems)\n        }\n\n        Write-PSFMessage -Level Verbose -Message \"Getting all Menu Items (Action) via the metadata provider.\"\n        $actionMenuItemModelInfos = $metadataProvider.MenuItemActions.GetPrimaryKeysWithModelInfo()\n\n        foreach ($tuple in $actionMenuItemModelInfos) {\n            $elementName = $tuple.Item1\n\n            Write-PSFMessage -Level Verbose -Message \"Working on: $elementName (MenuItemAction)\" -Target $elementName\n\n            $modelInfoNames = $tuple.Item2 | Select-Object -ExpandProperty Name # convert list of ModelInfo objects to list of Names\n            $modelNames = [string]::Join(\"; \", $modelInfoNames);\n\n            $element = $metadataProvider.MenuItemActions.Read($elementName)\n\n            $outItems = New-Object PSObject -Property @{ # create a hash table of the name/value pair\n                Name         = $element.Name\n                MenuItemType = \"Action\"\n                Models       = $modelNames\n                ObjectType   = $element.ObjectType\n                Object       = $element.Object\n                ConfigKey    = $element.ConfigurationKey\n                Enabled      = $element.Enabled\n                LabelID      = $element.Label\n                Label        = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.Label)\n            }\n\n            $menuItems.Add($outItems)\n        }\n    \n        Write-PSFMessage -Level Verbose -Message \"Getting all Menu Items (Output) via the metadata provider.\"\n        $outputMenuItemModelInfos = $metadataProvider.MenuItemOutputs.GetPrimaryKeysWithModelInfo()\n\n        foreach ($tuple in $outputMenuItemModelInfos) {\n            $elementName = $tuple.Item1\n\n            Write-PSFMessage -Level Verbose -Message \"Working on: $elementName (MenuItemOutput)\" -Target $elementName\n\n            $modelInfoNames = $tuple.Item2 | Select-Object -ExpandProperty Name # convert list of ModelInfo objects to list of Names\n            $modelNames = [string]::Join(\"; \", $modelInfoNames);\n\n            $element = $metadataProvider.MenuItemOutputs.Read($elementName)\n\n            $outItems = New-Object PSObject -Property @{ # create a hash table of the name/value pair\n                Name         = $element.Name\n                MenuItemType = \"Output\"\n                Models       = $modelNames\n                ObjectType   = $element.ObjectType\n                Object       = $element.Object\n                ConfigKey    = $element.ConfigurationKey\n                Enabled      = $element.Enabled\n                LabelID      = $element.Label\n                Label        = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.Label)\n            }\n\n            $menuItems.Add($outItems)\n        }\n        \n        $reportName = \"MenuItems\"\n        $sheetName = \"$reportName`_$version\"\n        $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length))\n\n        $menuItems | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName\n\n        [PSCustomObject]@{\n            Report = $reportName\n            File     = $outputFile\n            Filename = (Split-Path $outputFile -Leaf)\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365generatereports.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate Report for all related objects\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all related objects and generate a metadata report for each\n        \n    .PARAMETER OutputPath\n        Path to where you want the report file to be saved\n        \n        The default value is: \"c:\\temp\\d365fo.tools\\\"\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365GenerateReports\n        \n        This will generate a report for each related object.\n        It will contain all the metadata and save it into a xlsx (Excel) file.\n        It will saved the file to \"c:\\temp\\d365fo.tools\\\"\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Invoke-D365GenerateReports {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    param (\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    process {\n        Invoke-TimeSignal -Start\n\n        $reports = @()\n\n        $reports += Invoke-D365GenerateReportAggregateDataEntity @PSBoundParameters\n        $reports += Invoke-D365GenerateReportAggregateMeasure @PSBoundParameters\n        $reports += Invoke-D365GenerateReportConfigKey @PSBoundParameters\n        $reports += Invoke-D365GenerateReportConfigKeyGroup @PSBoundParameters\n        $reports += Invoke-D365GenerateReportDataEntity @PSBoundParameters\n        $reports += Invoke-D365GenerateReportDataEntityField @PSBoundParameters\n        $reports += Invoke-D365GenerateReportKpi @PSBoundParameters\n        $reports += Invoke-D365GenerateReportLicenseCode @PSBoundParameters\n        $reports += Invoke-D365GenerateReportMenuItem @PSBoundParameters\n        $reports += Invoke-D365GenerateReportSsrs @PSBoundParameters\n        $reports += Invoke-D365GenerateReportTable @PSBoundParameters\n        $reports += Invoke-D365GenerateReportWorkflowType @PSBoundParameters\n\n        Invoke-TimeSignal -End\n\n        $reports\n\n\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365generatereportssrs.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate Report for SSRS Report\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all SSRS Reports and generate a metadata report\n        \n    .PARAMETER OutputPath\n        Path to where you want the report file to be saved\n        \n        The default value is: \"c:\\temp\\d365fo.tools\\\"\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365GenerateReportSsrs\n        \n        This will generate a report.\n        It will contain all the metadata and save it into a xlsx (Excel) file.\n        It will saved the file to \"c:\\temp\\d365fo.tools\\\"\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nfunction Invoke-D365GenerateReportSsrs {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    param (\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    begin {\n        $outputFile = Join-Path -Path $OutputPath -ChildPath \"SSRSReports.xlsx\"\n\n        Import-GenerateReportAssemblies\n\n        $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n        $providerConfig.XppMetadataPath = $PackageDirectory\n        $providerConfig.MetadataPath = $PackageDirectory\n\n        $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig)\n\n        $productVersionDetails = Get-D365ProductInformation\n        \n        if (-not $productVersionDetails.ApplicationBuildVersion) {\n            $version = $productVersionDetails.ApplicationVersion\n        }\n        else {\n            $version = $productVersionDetails.ApplicationBuildVersion\n        }\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        Write-PSFMessage -Level Verbose -Message \"Getting all SSRS Reports via the metadata provider.\"\n        $reportsModelInfos = $metadataProvider.Reports.GetPrimaryKeysWithModelInfo()\n\n        #array of the names of all the reports that use Print Management (used PrintMgmtReportFormat table from Application Explorer)\n        $printMgmtReports = @(\"SalesInvoice\", \"SalesConfirm\", \"SalesPackingSlip\", \"WMSPickingList_OrderPick\", \"FreeTestInvoice\", \"SalesQuotationConfirmation\",\n            \"SalesQuotation\", \"VendInvoiceDocument\", \"PurchPackingSlip\", \"PurchReceiptsList\", \"PurchPurchaseOrder\", \"ProjInvoice\",\n            \"PurchRFQFormLetter_Send\", \"CustInterestNote\", \"CustCOllectionJour\", \"CustAccountStatementExt\", \"AgreementConfirmation\", \"PSAQuotations\",\n            \"PSAProjInvoice\", \"PSAContractLineInvoice\", \"PSAManageInvoice\", \"PSAManageInvoiceBR\", \"PSACustRetentionReleaseInvoice\")\n\n        $reports = New-Object System.Collections.Generic.List[object]\n\n        foreach ($tuple in $reportsModelInfos) {\n            $elementName = $tuple.Item1\n\n            Write-PSFMessage -Level Verbose -Message \"Working on: $elementName (SsrsReport)\" -Target $elementName\n\n            $element = $metadataProvider.Reports.Read($elementName)\n\n            $printMgmt = $($printMgmtReports -contains $element.Name)\n\n            foreach ($i in $element.DataSets) {\n                #filter out system fields\n                $fields = @()\n                foreach ($j in $i.Fields) {\n                    if ($j -notlike \"AX_*\") {\n                        $fields += $j\n                    }\n                }\n                \n                $filters = @()\n                #filter out system parameters\n                foreach ($k in $i.Parameters) {\n                    if ($k -notlike \"AX_*\") {\n                        $filters += $k\n                    }\n                }\n                  \n                $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair\n                    Name      = $element.Name\n                    DataSet   = $i.Name\n                    Filters   = [string]::Join(\", \", $filters)\n                    Fields    = [string]::Join(\", \", $fields)\n                    PrintMgmt = $printMgmt\n                }\n\n                $reports.Add($outItems)\n            }\n        }\n        \n        $reportName = \"SSRSReports\"\n        $sheetName = \"$reportName`_$version\"\n        $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length))\n\n        $reports | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName\n\n        [PSCustomObject]@{\n            Report   = $reportName\n            File     = $outputFile\n            Filename = (Split-Path $outputFile -Leaf)\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365generatereporttable.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate Report for Table\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all Tables and generate a metadata report\n        \n    .PARAMETER OutputPath\n        Path to where you want the report file to be saved\n        \n        The default value is: \"c:\\temp\\d365fo.tools\\\"\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365GenerateReportTable\n        \n        This will generate a report.\n        It will contain all the metadata and save it into a xlsx (Excel) file.\n        It will saved the file to \"c:\\temp\\d365fo.tools\\\"\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nfunction Invoke-D365GenerateReportTable {\n    [CmdletBinding()]\n    param (\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    begin {\n        $outputFile = Join-Path -Path $OutputPath -ChildPath \"Tables.xlsx\"\n\n        Import-GenerateReportAssemblies\n\n        $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n        $providerConfig.XppMetadataPath = $PackageDirectory\n        $providerConfig.MetadataPath = $PackageDirectory\n\n        $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig)\n\n        $productVersionDetails = Get-D365ProductInformation\n        \n        if (-not $productVersionDetails.ApplicationBuildVersion) {\n            $version = $productVersionDetails.ApplicationVersion\n        }\n        else {\n            $version = $productVersionDetails.ApplicationBuildVersion\n        }\n\n        Write-PSFMessage -Level Warning -Message \"Generating the Table report will take a long time. If you want to see progress while it is working, use the -Verbose parameter option\"\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        $dataEntities = Get-AxDataEntities -BinDir $BinDir -PackageDirectory $PackageDirectory\n        $forms = Get-AxForms -BinDir $BinDir -PackageDirectory $PackageDirectory\n        $views = Get-AxViews -BinDir $BinDir -PackageDirectory $PackageDirectory\n\n        Write-PSFMessage -Level Verbose -Message \"Getting all SSRS Reports via the metadata provider.\"\n        $tablesModelInfos = $metadataProvider.Tables.GetPrimaryKeysWithModelInfo()\n\n        #declare variables\n        $entityOrView\n        $crossCompany = \"\"\n    \n        $tables = New-Object System.Collections.Generic.List[object]\n\n        foreach ($tuple in $tablesModelInfos) {\n            $elementName = $tuple.Item1\n\n            Write-PSFMessage -Level Verbose -Message \"Working on: $elementName (Table)\" -Target $elementName\n\n            $element = $metadataProvider.Tables.Read($elementName)\n\n            #check if table is used in an entity\n            $entityMatch = \"No\"\n            foreach ($i in $dataEntities) {\n                if ($i.DataSource) {\n                    if ($i.DataSource.StartsWith($element.Name + \" [\")) {\n                        $entityMatch = \"Yes\"\n                    }\n                }\n            }\n\n            #check if table is used in a view\n            $viewMatch = \"No\"\n            foreach ($i in $views) {\n                foreach ($k in $i.DataSources) {\n                  \n                    if ($element.Name -eq $k.Name) {\n                        $viewMatch = \"Yes\"\n                    }\n                }\n            }\n\n            if ($viewMatch -eq \"Yes\" -or $entityMatch -eq \"Yes\") {\n                $entityOrView = \"Yes\"\n            }\n            else {\n                $entityOrView = \"No\"\n            }\n\n            #check if form's data source is the table and then taking CrossCompanyAutoQuery property\n            foreach ($i in $forms) {\n                foreach ($k in $i.DataSources) {\n                    if ($k.Name -eq $element.Name) {\n                        $crossCompany = $k.CrossCompanyAutoQuery\n                        if ($crossCompany -eq \"\") {\n                            $crossCompany = \"No\"\n                        }\n                    }\n                }\n            }\n\n            $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair\n                Name         = $element.Name\n                TableGroup   = $element.TableGroup\n                CrossCompany = $crossCompany\n                SystemTable  = $element.SystemTable\n                Indexes      = [string]::Join(\", \", $element.Indexes)\n                EntityOrView = $entityOrView\n            }\n\n            $tables.Add($outItems)\n        }\n\n        $reportName = \"Tables\"\n        $sheetName = \"$reportName`_$version\"\n        $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length))\n\n        $tables | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName\n\n        [PSCustomObject]@{\n            Report = $reportName\n            File     = $outputFile\n            Filename = (Split-Path $outputFile -Leaf)\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365generatereportworkflowtype.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate Report for Workflow Type\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all Workflow Types and generate a metadata report\n        \n    .PARAMETER OutputPath\n        Path to where you want the report file to be saved\n        \n        The default value is: \"c:\\temp\\d365fo.tools\\\"\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365GenerateReportWorkflowType\n        \n        This will generate a report.\n        It will contain all the metadata and save it into a xlsx (Excel) file.\n        It will saved the file to \"c:\\temp\\d365fo.tools\\\"\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nfunction Invoke-D365GenerateReportWorkflowType {\n    [CmdletBinding()]\n    param (\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    begin {\n        $outputFile = Join-Path -Path $OutputPath -ChildPath \"WorkflowTypes.xlsx\"\n\n        Import-GenerateReportAssemblies\n\n        $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n        $providerConfig.XppMetadataPath = $PackageDirectory\n        $providerConfig.MetadataPath = $PackageDirectory\n\n        $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig)\n\n        $productVersionDetails = Get-D365ProductInformation\n        \n        if (-not $productVersionDetails.ApplicationBuildVersion) {\n            $version = $productVersionDetails.ApplicationVersion\n        }\n        else {\n            $version = $productVersionDetails.ApplicationBuildVersion\n        }\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        Write-PSFMessage -Level Verbose -Message \"Getting all SSRS Reports via the metadata provider.\"\n        $workflowTypesModelInfos = $metadataProvider.WorkflowTemplates.GetPrimaryKeysWithModelInfo()\n        \n        $workflowTypes = New-Object System.Collections.Generic.List[object]\n\n        foreach ($tuple in $workflowTypesModelInfos) {\n            $elementName = $tuple.Item1\n\n            Write-PSFMessage -Level Verbose -Message \"Working on: $elementName (WorkflowType)\" -Target $elementName\n\n            $element = $metadataProvider.WorkflowTemplates.Read($elementName)\n\n            foreach ($supportedElement in $element.SupportedElements) {\n                $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair\n                    Name            = $element.Name\n                    Label           = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.Label)\n                    HelpText        = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.HelpText)\n                    AssociationType = $element.AssociationType\n                    Category        = $element.Category\n                    Participant     = $supportedElement.Name\n                    Role            = $supportedElement.Type\n                }\n            }\n\n            $workflowTypes.Add($outItems)\n        }\n\n        $reportName = \"WorkflowTypes\"\n        $sheetName = \"$reportName`_$version\"\n        $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length))\n\n        $workflowTypes | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName\n\n        [PSCustomObject]@{\n            Report   = $reportName\n            File     = $outputFile\n            Filename = (Split-Path $outputFile -Leaf)\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365installazcopy.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Download AzCopy.exe to your machine\n        \n    .DESCRIPTION\n        Download and extract the AzCopy.exe to your machine\n        \n    .PARAMETER Url\n        Url/Uri to where the latest AzCopy download is located\n        \n        The default value is for v10 as of writing\n        \n    .PARAMETER Path\n        Path to where you want the AzCopy to be extracted to\n        \n        Default value is: \"C:\\temp\\d365fo.tools\\AzCopy\\AzCopy.exe\"\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365InstallAzCopy -Path \"C:\\temp\\d365fo.tools\\AzCopy\\AzCopy.exe\"\n        \n        This will update the path for the AzCopy.exe in the modules configuration\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Invoke-D365InstallAzCopy {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [string] $Url = \"https://aka.ms/downloadazcopy-v10-windows\",\n\n        [string] $Path = \"C:\\temp\\d365fo.tools\\AzCopy\\AzCopy.exe\"\n    )\n\n    $azCopyFolder = Split-Path $Path -Parent\n    $downloadPath = Join-Path -Path $azCopyFolder -ChildPath \"AzCopy.zip\"\n\n    if (-not (Test-PathExists -Path $azCopyFolder -Type Container -Create)) { return }\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    Write-PSFMessage -Level Verbose -Message \"Downloading AzCopy.zip from the internet. $($Url)\" -Target $Url\n    (New-Object System.Net.WebClient).DownloadFile($Url, $downloadPath)\n\n    if (-not (Test-PathExists -Path $downloadPath -Type Leaf)) { return }\n\n    Unblock-File -Path $downloadPath\n\n    $tempExtractPath = Join-Path -Path $azCopyFolder -ChildPath \"Temp\"\n\n    Expand-Archive -Path $downloadPath -DestinationPath $tempExtractPath -Force\n\n    $null = (Get-Item \"$tempExtractPath\\*\\azcopy.exe\").CopyTo($Path, $true)\n\n    $tempExtractPath | Remove-Item -Force -Recurse\n    $downloadPath | Remove-Item -Force -Recurse\n\n    Set-D365AzCopyPath -Path $Path\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365installlicense.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Install a license for a 3. party solution\n        \n    .DESCRIPTION\n        Install a license for a 3. party solution using the builtin \"Microsoft.Dynamics.AX.Deployment.Setup.exe\" executable\n        \n    .PARAMETER Path\n        Path to the license file\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365InstallLicense -Path c:\\temp\\d365fo.tools\\license.txt\n        \n        This will use the default paths and start the Microsoft.Dynamics.AX.Deployment.Setup.exe with the needed parameters to import / install the license file.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365InstallLicense -Path c:\\temp\\d365fo.tools\\license.txt -ShowOriginalProgress\n        \n        This will use the default paths and start the Microsoft.Dynamics.AX.Deployment.Setup.exe with the needed parameters to import / install the license file.\n        The output from the installation process will be written to the console / host.\n        \n    .NOTES\n        Tags: License, Install, ISV, 3. Party, Servicing\n        \n        Author: Mötz Jensen (@splaxi)\n        \n#>\nfunction Invoke-D365InstallLicense {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $True)]\n        [Alias('File')]\n        [string] $Path,\n\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [string] $MetaDataDir = \"$Script:MetaDataDir\",\n\n        [string] $BinDir = \"$Script:BinDir\",\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\InstallLicense\"),\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly\n    )\n\n    $executable = Join-Path -Path $BinDir -ChildPath \"bin\\Microsoft.Dynamics.AX.Deployment.Setup.exe\"\n\n    if (-not (Test-PathExists -Path $MetaDataDir,$BinDir -Type Container)) {return}\n    if (-not (Test-PathExists -Path $Path,$executable -Type Leaf)) {return}\n\n    Invoke-TimeSignal -Start\n\n    $params = @(\"-isemulated\", \"true\",\n        \"-sqluser\", \"$SqlUser\",\n        \"-sqlpwd\", \"$SqlPwd\",\n        \"-sqlserver\", \"$DatabaseServer\",\n        \"-sqldatabase\", \"$DatabaseName\",\n        \"-metadatadir\", \"$MetaDataDir\",\n        \"-bindir\", \"$BinDir\",\n        \"-setupmode\", \"importlicensefile\",\n        \"-licensefilename\", \"`\"$Path`\"\")\n\n    Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365installnuget.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Download nuget.exe to your machine\n        \n    .DESCRIPTION\n        Download the nuget.exe to your machine\n        \n        By default it will download the latest version\n        \n    .PARAMETER Path\n        Path to where you want the nuget.exe to be downloaded to\n        \n        Default value is: \"C:\\temp\\d365fo.tools\\nuget\\nuget.exe\"\n        \n    .PARAMETER Url\n        Url/Uri to where the latest nuget download is located\n        \n        The default value is \"https://dist.nuget.org/win-x86-commandline/latest/nuget.exe\"\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365InstallNuget\n        \n        This will download the latest version of nuget.\n        The install path is identified by the default value: \"C:\\temp\\d365fo.tools\\nuget\\nuget.exe\".\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Invoke-D365InstallNuget {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [string] $Path = \"C:\\temp\\d365fo.tools\\nuget\",\n\n        [string] $Url = \"https://dist.nuget.org/win-x86-commandline/latest/nuget.exe\"\n    )\n\n    $downloadPath = Join-Path -Path $Path -ChildPath \"nuget.exe\"\n\n    if (-not (Test-PathExists -Path $Path -Type Container -Create)) { return }\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    Write-PSFMessage -Level Verbose -Message \"Downloading nuget.exe from the internet. $($Url)\" -Target $Url\n    (New-Object System.Net.WebClient).DownloadFile($Url, $downloadPath)\n\n    if (-not (Test-PathExists -Path $downloadPath -Type Leaf)) { return }\n\n    Unblock-File -Path $downloadPath\n\n    Set-D365NugetPath -Path $downloadPath\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365installsqlpackage.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Download SqlPackage.exe to your machine\n        \n    .DESCRIPTION\n        Download and extract SqlPackage.exe to your machine.\n        \n    .PARAMETER Path\n        Path to where you want the SqlPackage to be extracted to\n        \n        Default value is: \"C:\\temp\\d365fo.tools\\SqlPackage\\SqlPackage.exe\"\n        \n    .PARAMETER Latest\n        Overrides the Url parameter and uses the latest download URL provided by the evergreen link https://aka.ms/sqlpackage-windows\n        \n    .PARAMETER Url\n        Url/Uri to where the SqlPackage download is located\n        \n        The default value is for version 162.2.111.2 as of writing.\n        \n        Further discussion can be found here: https://github.com/d365collaborative/d365fo.tools/discussions/816\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365InstallSqlPackage\n        \n        This will download and extract SqlPackage.exe.\n        It will use the default value for the Path parameter, for where to save the SqlPackage.exe.\n        It will update the path for the SqlPackage.exe in configuration.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365InstallSqlPackage -Path \"C:\\temp\\SqlPackage\"\n        \n        This will download and extract SqlPackage.exe.\n        It will save the SqlPackage.exe to \"C:\\temp\\SqlPackage\".\n        It will update the path for the SqlPackage.exe in configuration.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365InstallSqlPackage -Latest\n        \n        This will download and extract the latest SqlPackage.exe.\n        It will use https://aka.ms/sqlpackage-windows as the download URL.\n        It will update the path for the SqlPackage.exe in configuration.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365InstallSqlPackage -Url \"https://go.microsoft.com/fwlink/?linkid=3030303\"\n        \n        This will download and extract SqlPackage.exe.\n        It will rely on the Url parameter to base the download on.\n        It will use the \"https://go.microsoft.com/fwlink/?linkid=3030303\" as value for the Url parameter.\n        It will update the path for the SqlPackage.exe in configuration.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        Author: Florian Hopfner (@FH-Inway)\n#>\n\nfunction Invoke-D365InstallSqlPackage {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding(DefaultParameterSetName = 'ImportUrl')]\n    [OutputType()]\n    param (\n        [Parameter(ParameterSetName = 'ImportUrl')]\n        [Parameter(ParameterSetName = 'ImportLatest')]\n        [string] $Path = \"C:\\temp\\d365fo.tools\\SqlPackage\",\n        \n        [Parameter(ParameterSetName = 'ImportLatest')]\n        [switch] $Latest,\n        \n        [Parameter(ParameterSetName = 'ImportUrl')]\n        [string] $Url = \"https://go.microsoft.com/fwlink/?linkid=2261576\"\n    )\n\n    if ($Latest) {\n        $Url = \"https://aka.ms/sqlpackage-windows\"\n    }\n\n    $sqlPackageFolder = $Path\n    $downloadPath = Join-Path -Path $sqlPackageFolder -ChildPath \"SqlPackage.zip\"\n\n    if (-not (Test-PathExists -Path $sqlPackageFolder -Type Container -Create)) { return }\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    Write-PSFMessage -Level Verbose -Message \"Downloading SqlPackage.zip from the internet. $($Url)\" -Target $Url\n    (New-Object System.Net.WebClient).DownloadFile($Url, $downloadPath)\n\n    if (-not (Test-PathExists -Path $downloadPath -Type Leaf)) { return }\n\n    Unblock-File -Path $downloadPath\n\n    $tempExtractPath = Join-Path -Path $sqlPackageFolder -ChildPath \"Temp\"\n\n    Expand-Archive -Path $downloadPath -DestinationPath $tempExtractPath -Force\n\n    Get-ChildItem -Path $tempExtractPath | Move-Item -Destination { $_.Directory.Parent.FullName } -Force\n\n    $tempExtractPath | Remove-Item -Force -Recurse\n    $downloadPath | Remove-Item -Force -Recurse\n\n    $SqlPackagePath = Join-Path -Path $Path -ChildPath \"SqlPackage.exe\"\n    Set-D365SqlPackagePath -Path $SqlPackagePath\n\n    $result = Invoke-Process -Path $SqlPackagePath -Params \"/Version\"\n    $version = $result.stdout -replace \"`r`n\", \"\"\n\n    Write-PSFMessage -Level Host -Message \"SqlPackage.exe version $version has been downloaded and extracted to $SqlPackagePath\"\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365lcsapirefreshtoken.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Refresh the token for lcs communication\n        \n    .DESCRIPTION\n        Invoke the refresh logic that refreshes the token object based on the ClientId and RefreshToken\n        \n    .PARAMETER ClientId\n        The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal\n        \n    .PARAMETER RefreshToken\n        The Refresh Token that you want to use for the authentication process\n        \n    .PARAMETER InputObject\n        The entire object that you received from the Get-D365LcsApiToken command, which contains the needed RefreshToken\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsApiRefreshToken -ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" -RefreshToken \"Tsdljfasfe2j32324\"\n        \n        This will refresh an OAuth 2.0 access token, and obtain a (new) valid OAuth 2.0 access token from Azure Active Directory.\n        The ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" is used in the OAuth 2.0 \"Refresh Token\" Grant Flow to authenticate.\n        The RefreshToken \"Tsdljfasfe2j32324\" is used to prove to Azure Active Directoy that we are allowed to obtain a new valid Access Token.\n        \n    .EXAMPLE\n        PS C:\\> $temp = Get-D365LcsApiToken -LcsApiUri \"https://lcsapi.eu.lcs.dynamics.com\" -ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" -Username \"serviceaccount@domain.com\" -Password \"TopSecretPassword\"\n        PS C:\\> $temp = Invoke-D365LcsApiRefreshToken -ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" -InputObject $temp\n        \n        This will refresh an OAuth 2.0 access token, and obtain a (new) valid OAuth 2.0 access token from Azure Active Directory.\n        This will obtain a new token object from the Get-D365LcsApiToken cmdlet and store it in $temp.\n        Then it will pass $temp to the Invoke-D365LcsApiRefreshToken along with the ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\".\n        The new token object will be save into $temp.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsApiConfig | Invoke-D365LcsApiRefreshToken | Set-D365LcsApiConfig\n        \n        This will refresh an OAuth 2.0 access token, and obtain a (new) valid OAuth 2.0 access token from Azure Active Directory.\n        This will fetch the current LCS API details from Get-D365LcsApiConfig.\n        The output from Get-D365LcsApiConfig is piped directly to Invoke-D365LcsApiRefreshToken, which will fetch a new token object.\n        The new token object is piped directly into Set-D365LcsApiConfig, which will save the needed details into the configuration store.\n        \n    .LINK\n        Get-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsApiToken\n        \n    .LINK\n        Get-D365LcsAssetValidationStatus\n        \n    .LINK\n        Get-D365LcsDeploymentStatus\n        \n    .LINK\n        Invoke-D365LcsDeployment\n        \n    .LINK\n        Invoke-D365LcsUpload\n        \n    .LINK\n        Set-D365LcsApiConfig\n        \n    .NOTES\n        Tags: LCS, API, Token, BearerToken\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Invoke-D365LcsApiRefreshToken {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseProcessBlockForPipelineCommand\", \"\")]\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = \"Simple\")]\n        [Parameter(Mandatory = $true, ParameterSetName = \"Object\")]\n        [string] $ClientId,\n\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = \"Simple\")]\n        [Alias('refresh_token')]\n        [Alias('Token')]\n        [string] $RefreshToken,\n\n        [Parameter(Mandatory = $false, ParameterSetName = \"Object\")]\n        [PSCustomObject] $InputObject,\n\n        [switch] $EnableException\n    )\n\n    if ($PsCmdlet.ParameterSetName -eq \"Simple\") {\n        Invoke-RefreshToken -AuthProviderUri $Script:AADOAuthEndpoint @PSBoundParameters\n    }\n    else {\n        Invoke-RefreshToken -AuthProviderUri $Script:AADOAuthEndpoint -ClientId $ClientId -RefreshToken $InputObject.refresh_token\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365lcsdatabaseexport.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Start a database export from an environment\n        \n    .DESCRIPTION\n        Start a database export from an environment from a LCS project\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER SourceEnvironmentId\n        The unique id of the environment that you want to use as the source for the database export\n        \n        The Id can be located inside the LCS portal\n        \n    .PARAMETER BackupName\n        Name of the backup file when it is being exported from the environment\n        \n        The file shouldn't contain any extension at all, just the desired file name\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER SkipInitialStatusFetch\n        Instruct the cmdlet to skip the first fetch of the database refresh status\n        \n        Useful when you have a large script that handles this status validation and you don't want to spend time with this cmdlet\n        \n        Default output from this cmdlet is 2 (two) different objects. The first object is the response object for starting the export operation. The second object is the response object from fetching the status of the export operation.\n        \n        Setting this parameter (activate it), will affect the number of output objects. If you skip, only the first response object outputted.\n        \n    .PARAMETER FailOnErrorMessage\n        Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n        \n        Used in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\n        This allows you to implement custom retry / error handling logic\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsDatabaseExport -ProjectId 123456789 -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -BackupName \"BackupViaApi\" -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will start the database export from the Source environment.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\n        The backup name is identified by the BackupName \"BackupViaApi\", which instructs the API to save the backup with that filename.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsDatabaseExport -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -BackupName \"BackupViaApi\"\n        \n        This will start the database export from the Source environment.\n        The source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\n        The backup name is identified by the BackupName \"BackupViaApi\", which instructs the API to save the backup with that filename.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> $databaseExport = Invoke-D365LcsDatabaseExport -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -BackupName \"BackupViaApi\" -SkipInitialStatusFetch\n        PS C:\\> $databaseExport | Get-D365LcsDatabaseOperationStatus -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e9\" -SleepInSeconds 60\n        \n        This will start the database export from the Source environment.\n        The source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\n        The backup name is identified by the BackupName \"BackupViaApi\", which instructs the API to save the backup with that filename.\n        It will skip the first database operation status fetch and only output the details from starting the export.\n        \n        The output from Invoke-D365LcsDatabaseExport is stored in the $databaseExport. This will enable you to pass the $databaseExport variable to other cmdlets which should make things easier for you.\n        \n        Will pipe the $databaseExport variable to the Get-D365LcsDatabaseOperationStatus cmdlet and get the status from the database export job.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsDatabaseExport -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -BackupName \"BackupViaApi\" -SkipInitialStatusFetch\n        \n        This will start the database export from the Source environment.\n        The source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\n        The backup name is identified by the BackupName \"BackupViaApi\", which instructs the API to save the backup with that filename.\n        It will skip the first database operation status fetch and only output the details from starting the export.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsDatabaseExport -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -BackupName \"BackupViaApi\" -RetryTimeout \"00:01:00\"\n        \n        This will start the database export from the Source environment, and allow for the cmdlet to retry for no more than 1 minute.\n        The source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\n        The backup name is identified by the BackupName \"BackupViaApi\", which instructs the API to save the backup with that filename.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .LINK\n        Get-D365LcsDatabaseOperationStatus\n        \n    .LINK\n        Get-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsApiToken\n        \n    .LINK\n        Get-D365LcsAssetValidationStatus\n        \n    .LINK\n        Get-D365LcsDeploymentStatus\n        \n    .LINK\n        Invoke-D365LcsApiRefreshToken\n        \n    .LINK\n        Invoke-D365LcsUpload\n        \n    .LINK\n        Set-D365LcsApiConfig\n        \n    .NOTES\n        The ActivityId property is a custom property that ISN'T part of the response from the LCS API. The ActivityId is always the same as the OperationActivityId (original LCS property).\n        The EnvironmentId property is a custom property that ISN'T part of the response from the LCS API. The EnvironmentId is always the same as the SourceEnvironmentId parameter you have supplied to this cmdlet.\n        \n        Default output from this cmdlet is 2 (two) different objects. The first object is the response object for starting the export operation. The second object is the response object from fetching the status of the export operation.\n        \n        Setting the SkipInitialStatusFetch parameter (activate it), will affect the number of output objects. If you skip, only the first response object outputted.\n        \n        Running with the default (SkipInitialStatusFetch NOT being set), will instruct the cmdlet to call the Get-D365LcsDatabaseOperationStatus cmdlet. This will output a second object, with other properties than the first object outputted.\n        \n        Tags: Environment, Config, Configuration, LCS, Database backup, Api, Backup, Bacpac\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Invoke-D365LcsDatabaseExport {\n    [CmdletBinding()]\n    [OutputType()]\n    param(\n        [int] $ProjectId = $Script:LcsApiProjectId,\n        \n        [Alias('Token')]\n        [string] $BearerToken = $Script:LcsApiBearerToken,\n\n        [Parameter(Mandatory = $true)]\n        [string] $SourceEnvironmentId,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $BackupName,\n\n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [switch] $SkipInitialStatusFetch,\n\n        [switch] $FailOnErrorMessage,\n        \n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    Invoke-TimeSignal -Start\n\n    if (-not ($BearerToken.StartsWith(\"Bearer \"))) {\n        $BearerToken = \"Bearer $BearerToken\"\n    }\n\n    $exportJob = Start-LcsDatabaseExportV2 -ProjectId $ProjectId -BearerToken $BearerToken -SourceEnvironmentId $SourceEnvironmentId -BackupName $BackupName -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    if ($FailOnErrorMessage -and $exportJob.ErrorMessage) {\n        $messageString = \"The request against LCS succeeded, but the response was an error message for the operation: <c='em'>$($exportJob.ErrorMessage)</c>.\"\n        $errorMessagePayload = \"`r`n$($exportJob | ConvertTo-Json)\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $exportJob\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $exportJob\n    }\n\n    $temp = [PSCustomObject]@{ EnvironmentId = \"$SourceEnvironmentId\"; OperationStatus = \"NotStarted\"; }\n    #Hack to silence the PSScriptAnalyzer\n    $temp | Out-Null\n \n    $exportJob | Select-PSFObject *, \"OperationActivityId as ActivityId\", \"EnvironmentId from temp as EnvironmentId\", \"OperationStatus from temp as OperationStatus\" -TypeName \"D365FO.TOOLS.LCS.Database.Operation.Status\"\n\n    if (-not $SkipInitialStatusFetch) {\n        Get-D365LcsDatabaseOperationStatus -ProjectId $ProjectId -BearerToken $BearerToken -OperationActivityId $($exportJob.OperationActivityId) -EnvironmentId $SourceEnvironmentId -LcsApiUri $LcsApiUri -WaitForCompletion:$false -SleepInSeconds 60\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365lcsdatabaserefresh.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Start a database refresh between 2 environments\n        \n    .DESCRIPTION\n        Start a database refresh between 2 environments from a LCS project\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER SourceEnvironmentId\n        The unique id of the environment that you want to use as the source for the database refresh\n        \n        The Id can be located inside the LCS portal\n        \n    .PARAMETER TargetEnvironmentId\n        The unique id of the environment that you want to use as the target for the database refresh\n        \n        The Id can be located inside the LCS portal\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER SkipInitialStatusFetch\n        Instruct the cmdlet to skip the first fetch of the database refresh status\n        \n        Useful when you have a large script that handles this status validation and you don't want to spend time with this cmdlet\n        \n        Default output from this cmdlet is 2 (two) different objects. The first object is the response object for starting the refresh operation. The second object is the response object from fetching the status of the refresh operation.\n        \n        Setting this parameter (activate it), will affect the number of output objects. If you skip, only the first response object outputted.\n        \n    .PARAMETER FailOnErrorMessage\n        Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n        \n        Used in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\n        This allows you to implement custom retry / error handling logic\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsDatabaseRefresh -ProjectId 123456789 -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will start the database refresh between the Source and Target environments.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\n        The target environment is identified by the TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsDatabaseRefresh -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n        \n        This will start the database refresh between the Source and Target environments.\n        The source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\n        The target environment is identified by the TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> $databaseRefresh = Invoke-D365LcsDatabaseRefresh -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -SkipInitialStatusFetch\n        PS C:\\> $databaseRefresh | Get-D365LcsDatabaseOperationStatus -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e9\" -SleepInSeconds 60\n        \n        This will start the database refresh between the Source and Target environments.\n        The source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\n        The target environment is identified by the TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        It will skip the first database refesh status fetch and only output the details from starting the refresh.\n        \n        The output from Invoke-D365LcsDatabaseRefresh is stored in the $databaseRefresh. This will enable you to pass the $databaseRefresh variable to other cmdlets which should make things easier for you.\n        \n        Will pipe the $databaseRefresh variable to the Get-D365LcsDatabaseOperationStatus cmdlet and get the status from the database refresh job.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsDatabaseRefresh -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -SkipInitialStatusFetch\n        \n        This will start the database refresh between the Source and Target environments.\n        The source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\n        The target environment is identified by the TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        It will skip the first database refesh status fetch and only output the details from starting the refresh.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsDatabaseRefresh -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -RetryTimeout \"00:01:00\"\n        \n        This will start the database refresh between the Source and Target environments, and allow for the cmdlet to retry for no more than 1 minute.\n        The source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\n        The target environment is identified by the TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .LINK\n        Get-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsApiToken\n        \n    .LINK\n        Get-D365LcsAssetValidationStatus\n        \n    .LINK\n        Get-D365LcsDeploymentStatus\n        \n    .LINK\n        Invoke-D365LcsApiRefreshToken\n        \n    .LINK\n        Invoke-D365LcsUpload\n        \n    .LINK\n        Set-D365LcsApiConfig\n        \n    .NOTES\n        The ActivityId property is a custom property that ISN'T part of the response from the LCS API. The ActivityId is always the same as the OperationActivityId (original LCS property).\n        The EnvironmentId property is a custom property that ISN'T part of the response from the LCS API. The EnvironmentId is always the same as the SourceEnvironmentId parameter you have supplied to this cmdlet.\n        \n        Default output from this cmdlet is 2 (two) different objects. The first object is the response object for starting the refresh operation. The second object is the response object from fetching the status of the refresh operation.\n        \n        Setting the SkipInitialStatusFetch parameter (activate it), will affect the number of output objects. If you skip, only the first response object outputted.\n        \n        Running with the default (SkipInitialStatusFetch NOT being set), will instruct the cmdlet to call the Get-D365LcsDatabaseOperationStatus cmdlet. This will output a second object, with other properties than the first object outputted.\n        \n        Tags: Environment, Config, Configuration, LCS, Database backup, Api, Backup, Restore, Refresh\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Invoke-D365LcsDatabaseRefresh {\n    [CmdletBinding()]\n    [OutputType()]\n    param(\n        [int] $ProjectId = $Script:LcsApiProjectId,\n        \n        [Alias('Token')]\n        [string] $BearerToken = $Script:LcsApiBearerToken,\n\n        [Parameter(Mandatory = $true)]\n        [string] $SourceEnvironmentId,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $TargetEnvironmentId,\n\n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [switch] $SkipInitialStatusFetch,\n\n        [switch] $FailOnErrorMessage,\n        \n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    Invoke-TimeSignal -Start\n\n    if (-not ($BearerToken.StartsWith(\"Bearer \"))) {\n        $BearerToken = \"Bearer $BearerToken\"\n    }\n\n    $refreshJob = Start-LcsDatabaseRefreshV2 -ProjectId $ProjectId -BearerToken $BearerToken -SourceEnvironmentId $SourceEnvironmentId -TargetEnvironmentId $TargetEnvironmentId -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    if ($FailOnErrorMessage -and $refreshJob.ErrorMessage) {\n        $messageString = \"The request against LCS succeeded, but the response was an error message for the operation: <c='em'>$($refreshJob.ErrorMessage)</c>.\"\n        $errorMessagePayload = \"`r`n$($refreshJob | ConvertTo-Json)\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $refreshJob\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $refreshJob\n    }\n    \n    $temp = [PSCustomObject]@{ EnvironmentId = \"$TargetEnvironmentId\"; OperationStatus = \"NotStarted\"; ProjectId = $ProjectId }\n    #Hack to silence the PSScriptAnalyzer\n    $temp | Out-Null\n \n    $refreshJob | Select-PSFObject *, \"OperationActivityId as ActivityId\", \"EnvironmentId from temp as EnvironmentId\", \"OperationStatus from temp as OperationStatus\", \"ProjectId from temp as ProjectId\" -TypeName \"D365FO.TOOLS.LCS.Database.Operation.Status\"\n\n    if (-not $SkipInitialStatusFetch) {\n        Get-D365LcsDatabaseOperationStatus -ProjectId $ProjectId -BearerToken $BearerToken -OperationActivityId $($refreshJob.OperationActivityId) -EnvironmentId $TargetEnvironmentId -LcsApiUri $LcsApiUri -WaitForCompletion:$false -SleepInSeconds 60\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365lcsdeployment.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Start the deployment of a deployable package\n        \n    .DESCRIPTION\n        Deploy a deployable package from the Asset Library from a LCS project using the API provided by Microsoft\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER AssetId\n        The unique id of the asset / file that you are trying to deploy from LCS\n        \n    .PARAMETER EnvironmentId\n        The unique id of the environment that you want to work against\n        \n        The Id can be located inside the LCS portal\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER UpdateName\n        Name of the update when you are working against Self-Service environments\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER FailOnErrorMessage\n        Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n        \n        Used in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\n        This allows you to implement custom retry / error handling logic\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsDeployment -ProjectId 123456789 -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -BearerToken \"Bearer JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will start the deployment of the file located in the Asset Library.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"Bearer JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsDeployment -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n        \n        This will start the deployment of the file located in the Asset Library.\n        The file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsDeployment -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -UpdateName \"Release_XYZ\"\n        \n        This will start the deployment of the file located in the Asset Library against a Self-Service environment.\n        The file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        The deployment is name \"Release_XYZ\" by setting the UpdateName parameter, which is mandatory when working against Self-Service environments.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsDeployment -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -RetryTimeout \"00:01:00\"\n        \n        This will start the deployment of the file located in the Asset Library, and allow for the cmdlet to retry for no more than 1 minute.\n        The file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .LINK\n        Get-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsApiToken\n        \n    .LINK\n        Get-D365LcsAssetValidationStatus\n        \n    .LINK\n        Get-D365LcsDeploymentStatus\n        \n    .LINK\n        Invoke-D365LcsApiRefreshToken\n        \n    .LINK\n        Invoke-D365LcsUpload\n        \n    .LINK\n        Set-D365LcsApiConfig\n        \n    .NOTES\n        Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token, Deployment, Deploy\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Invoke-D365LcsDeployment {\n    [CmdletBinding(DefaultParameterSetName = \"VM\")]\n    [OutputType()]\n    param(\n        [int] $ProjectId = $Script:LcsApiProjectId,\n        \n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]\n        [string] $AssetId,\n\n        [Parameter(Mandatory = $true)]\n        [string] $EnvironmentId,\n        \n        [Parameter(ParameterSetName = \"Self-Service\", Mandatory = $true)]\n        [string] $UpdateName,\n\n        [Alias('Token')]\n        [string] $BearerToken = $Script:LcsApiBearerToken,\n\n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [switch] $FailOnErrorMessage,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    process {\n        Invoke-TimeSignal -Start\n\n        if (-not ($BearerToken.StartsWith(\"Bearer \"))) {\n            $BearerToken = \"Bearer $BearerToken\"\n        }\n\n        $deploymentStatus = Start-LcsDeploymentV2 -BearerToken $BearerToken -ProjectId $ProjectId -AssetId $AssetId -EnvironmentId $EnvironmentId -UpdateName $UpdateName -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        if ($FailOnErrorMessage -and $deploymentStatus.ErrorMessage) {\n            $messageString = \"The request against LCS succeeded, but the response was an error message for the operation: <c='em'>$($deploymentStatus.ErrorMessage)</c>.\"\n            $errorMessagePayload = \"`r`n$($deploymentStatus | ConvertTo-Json)\"\n            Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus\n            Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus\n        }\n\n        $temp = [PSCustomObject]@{ EnvironmentId = \"$TargetEnvironmentId\"; OperationStatus = \"NotStarted\"; ProjectId = $ProjectId }\n        #Hack to silence the PSScriptAnalyzer\n        $temp | Out-Null\n\n        $deploymentStatus | Select-PSFObject *, \"OperationActivityId as ActivityId\", \"EnvironmentId from temp as EnvironmentId\", \"OperationStatus from temp as OperationStatus\", \"ProjectId from temp as ProjectId\" -TypeName \"D365FO.TOOLS.LCS.Deployment.Operation.Status\"\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365lcsenvironmentstart.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Start a specified environment through LCS.\n        \n    .DESCRIPTION\n        Start a specified IAAS environment that is Customer Managed through the LCS API.\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER EnvironmentId\n        The unique id of the environment that you want to take action upon\n        \n        The Id can be located inside the LCS portal\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER FailOnErrorMessage\n        Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n        \n        Used in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\n        This allows you to implement custom retry / error handling logic\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsEnvironmentStart -ProjectId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will trigger the environment start operation upon the given environment through the LCS API.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsEnvironmentStart -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n        \n        This will trigger the environment start operation upon the given environment through the LCS API.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsEnvironmentStart -ProjectId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -RetryTimeout \"00:01:00\"\n        \n        This will trigger the environment start operation upon the given environment through the LCS API, and allow for the cmdlet to retry for no more than 1 minute.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .LINK\n        Get-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsApiToken\n        \n    .LINK\n        Invoke-D365LcsApiRefreshToken\n        \n    .LINK\n        Set-D365LcsApiConfig\n        \n    .LINK\n        Invoke-D365LcsEnvironmentStop\n        \n    .NOTES\n        Only Customer Managed IAAS environments are supported with this API.\n        Microsoft Managed IAAS environments need to remain online to allow for Microsoft update operations and are not supported with this API.\n        Self-service environments do not have a stop functionality and will not work with this API.\n        \n        Tags: Environment, Start, StartStop, Stop, LCS, Api\n        \n        Author: Mötz Jensen (@Splaxi), Billy Richardson (@richardsondev)\n        \n#>\n\nfunction Invoke-D365LcsEnvironmentStart {\n    [CmdletBinding()]\n    [OutputType()]\n    param(\n        [int] $ProjectId = $Script:LcsApiProjectId,\n        \n        [Alias('Token')]\n        [string] $BearerToken = $Script:LcsApiBearerToken,\n\n        [Parameter(Mandatory = $true)]\n        [string] $EnvironmentId,\n        \n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [switch] $FailOnErrorMessage,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    Invoke-TimeSignal -Start\n\n    if (-not ($BearerToken.StartsWith(\"Bearer \"))) {\n        $BearerToken = \"Bearer $BearerToken\"\n    }\n\n    $environmentAction = Start-LcsEnvironmentStartStopV2 -ProjectId $ProjectId -BearerToken $BearerToken -EnvironmentId $EnvironmentId -IsStop $False -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    if ($FailOnErrorMessage -and $environmentAction.ErrorMessage) {\n        $messageString = \"The request against LCS succeeded, but the response was an error message for the operation: <c='em'>$($environmentAction.ErrorMessage)</c>.\"\n        $errorMessagePayload = \"`r`n$($environmentAction | ConvertTo-Json)\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $environmentAction\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $environmentAction\n    }\n\n    $temp = [PSCustomObject]@{ EnvironmentId = \"$EnvironmentId\"; ProjectId = $ProjectId }\n    #Hack to silence the PSScriptAnalyzer\n    $temp | Out-Null\n\n    $environmentAction | Select-PSFObject *, \"OperationActivityId as ActivityId\", \"EnvironmentId from temp as EnvironmentId\", \"ProjectId from temp as ProjectId\" -TypeName \"D365FO.TOOLS.LCS.Environment.Operation.Status\"\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365lcsenvironmentstop.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Stop a specified environment through LCS.\n        \n    .DESCRIPTION\n        Stop a specified IAAS environment that is Customer Managed through the LCS API.\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER EnvironmentId\n        The unique id of the environment that you want to take action upon\n        \n        The Id can be located inside the LCS portal\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER FailOnErrorMessage\n        Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n        \n        Used in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\n        This allows you to implement custom retry / error handling logic\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsEnvironmentStop -ProjectId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will trigger the environment stop operation upon the given environment through the LCS API.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsEnvironmentStop -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n        \n        This will trigger the environment stop operation upon the given environment through the LCS API.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsEnvironmentStop -ProjectId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -RetryTimeout \"00:01:00\"\n        \n        This will trigger the environment stop operation upon the given environment through the LCS API, and allow for the cmdlet to retry for no more than 1 minute.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .LINK\n        Get-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsApiToken\n        \n    .LINK\n        Invoke-D365LcsApiRefreshToken\n        \n    .LINK\n        Set-D365LcsApiConfig\n        \n    .LINK\n        Invoke-D365LcsEnvironmentStart\n        \n    .NOTES\n        Only Customer Managed IAAS environments are supported with this API.\n        Microsoft Managed IAAS environments need to remain online to allow for Microsoft update operations and are not supported with this API.\n        Self-service environments do not have a stop functionality and will not work with this API.\n        \n        Tags: Environment, Stop, StartStop, Start, LCS, Api\n        \n        Author: Mötz Jensen (@Splaxi), Billy Richardson (@richardsondev)\n        \n#>\n\nfunction Invoke-D365LcsEnvironmentStop {\n    [CmdletBinding()]\n    [OutputType()]\n    param(\n        [int] $ProjectId = $Script:LcsApiProjectId,\n        \n        [Alias('Token')]\n        [string] $BearerToken = $Script:LcsApiBearerToken,\n\n        [Parameter(Mandatory = $true)]\n        [string] $EnvironmentId,\n        \n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [switch] $FailOnErrorMessage,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    Invoke-TimeSignal -Start\n\n    if (-not ($BearerToken.StartsWith(\"Bearer \"))) {\n        $BearerToken = \"Bearer $BearerToken\"\n    }\n\n    $environmentAction = Start-LcsEnvironmentStartStopV2 -ProjectId $ProjectId -BearerToken $BearerToken -EnvironmentId $EnvironmentId -IsStop $True -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    if ($FailOnErrorMessage -and $environmentAction.ErrorMessage) {\n        $messageString = \"The request against LCS succeeded, but the response was an error message for the operation: <c='em'>$($environmentAction.ErrorMessage)</c>.\"\n        $errorMessagePayload = \"`r`n$($environmentAction | ConvertTo-Json)\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $environmentAction\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $environmentAction\n    }\n\n    $temp = [PSCustomObject]@{ EnvironmentId = \"$EnvironmentId\"; ProjectId = $ProjectId }\n    #Hack to silence the PSScriptAnalyzer\n    $temp | Out-Null\n\n    $environmentAction | Select-PSFObject *, \"OperationActivityId as ActivityId\", \"EnvironmentId from temp as EnvironmentId\", \"ProjectId from temp as ProjectId\" -TypeName \"D365FO.TOOLS.LCS.Environment.Operation.Status\"\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365lcsupload.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Upload a file to a LCS project\n        \n    .DESCRIPTION\n        Upload a file to a LCS project using the API provided by Microsoft\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER FilePath\n        Path to the file that you want to upload to the Asset Library on LCS\n        \n    .PARAMETER FileType\n        Type of file you want to upload\n        \n        Valid options:\n        \"Model\"\n        \"Process Data Package\"\n        \"Software Deployable Package\"\n        \"GER Configuration\"\n        \"Data Package\"\n        \"PowerBI Report Model\"\n        \"E-Commerce Package\"\n        \"NuGet Package\"\n        \"Retail Self-Service Package\"\n        \"Commerce Cloud Scale Unit Extension\"\n        \n        Default value is \"Software Deployable Package\"\n        \n    .PARAMETER Name\n        Name to be assigned / shown on LCS\n        \n    .PARAMETER Filename\n        Filename to be assigned / shown on LCS\n        \n        Often will it require an extension for it to be accepted\n        \n    .PARAMETER FileDescription\n        Description to be assigned / shown on LCS\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER FailOnErrorMessage\n        Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n        \n        Used in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\n        This allows you to implement custom retry / error handling logic\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsUpload -ProjectId 123456789 -BearerToken \"Bearer JldjfafLJdfjlfsalfd...\" -FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\" -FileType \"SoftwareDeployablePackage\" -Name \"Release-2019-05-05\" -Filename \"Release-2019-05-05.zip\" -FileDescription \"Build based on sprint: SuperSprint-1\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will start the upload of a file to the Asset Library.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The file that will be uploaded is based on the FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\".\n        The file type \"Software Deployable Package\" determines where inside the Asset Library the file will end up.\n        The name inside the Asset Library is based on the Name \"Release-2019-05-05\".\n        The file name inside the Asset Library is based on the FileName \"Release-2019-05-05.zip\".\n        The description inside the Asset Library is based on the FileDescription \"Build based on sprint: SuperSprint-1\".\n        The request will authenticate with the BearerToken \"Bearer JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsUpload -FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\" -FileType \"SoftwareDeployablePackage\" -FileName \"Release-2019-05-05.zip\"\n        \n        This will start the upload of a file to the Asset Library.\n        The file that will be uploaded is based on the FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\".\n        The file type \"Software Deployable Package\" determines where inside the Asset Library the file will end up.\n        The file name inside the Asset Library is based on the FileName \"Release-2019-05-05.zip\".\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsUpload -FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\"\n        \n        This will start the upload of a file to the Asset Library.\n        The file that will be uploaded is based on the FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\".\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365LcsUpload -FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\" -RetryTimeout \"00:01:00\"\n        \n        This will start the upload of a file to the Asset Library through the LCS API, and allow for the cmdlet to retry for no more than 1 minute.\n        The file that will be uploaded is based on the FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\".\n        \n        All default values will come from the configuration available from Get-D365LcsApiConfig.\n        \n        The default values can be configured using Set-D365LcsApiConfig.\n        \n    .LINK\n        Get-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsApiToken\n        \n    .LINK\n        Get-D365LcsAssetValidationStatus\n        \n    .LINK\n        Get-D365LcsDeploymentStatus\n        \n    .LINK\n        Invoke-D365LcsApiRefreshToken\n        \n    .LINK\n        Invoke-D365LcsDeployment\n        \n    .LINK\n        Set-D365LcsApiConfig\n        \n    .NOTES\n        Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Invoke-D365LcsUpload {\n    [CmdletBinding()]\n    [OutputType()]\n    param(\n        [int]$ProjectId = $Script:LcsApiProjectId,\n        \n        [Alias('Token')]\n        [string] $BearerToken = $Script:LcsApiBearerToken,\n\n        [Parameter(Mandatory = $true)]\n        [string] $FilePath,\n\n        [LcsAssetFileType] $FileType = [LcsAssetFileType]::SoftwareDeployablePackage,\n\n        [string] $Name,\n\n        [string] $Filename,\n\n        [string] $FileDescription,\n\n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [switch] $FailOnErrorMessage,\n        \n        [Timespan] $RetryTimeout = \"00:00:00\",\n        \n        [switch] $EnableException\n    )\n\n    Invoke-TimeSignal -Start\n\n    $fileNameExtracted = Split-Path $FilePath -Leaf\n\n    if ($Filename -eq \"\") {\n        $Filename = $fileNameExtracted\n    }\n\n    if ($Name -eq \"\") {\n        $Name = [System.IO.Path]::GetFileNameWithoutExtension($FilePath)\n    }\n\n    if (-not ($BearerToken.StartsWith(\"Bearer \"))) {\n        $BearerToken = \"Bearer $BearerToken\"\n    }\n    \n    $blobDetails = Start-LcsUploadV2 -Token $BearerToken -ProjectId $ProjectId -FileType $FileType -LcsApiUri $LcsApiUri -Name $Name -FileName $Filename -Description $FileDescription -RetryTimeout $RetryTimeout\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    if ($FailOnErrorMessage -and $blobDetails.ErrorMessage) {\n        $messageString = \"The request against LCS succeeded, but the response was an error message for the operation: <c='em'>$($blobDetails.ErrorMessage)</c>.\"\n        $errorMessagePayload = \"`r`n$($blobDetails | ConvertTo-Json)\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $blobDetails\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $blobDetails\n    }\n\n    Write-PSFMessage -Level Verbose -Message \"Start response\" -Target $blobDetails\n\n    $uploadResponse = Copy-FileToLcsBlob -FilePath $FilePath -FullUri $blobDetails.FileLocation\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    Write-PSFMessage -Level Verbose -Message \"Upload response\" -Target $uploadResponse\n\n    $ackResponse = Complete-LcsUploadV2 -Token $BearerToken -ProjectId $ProjectId -AssetId $blobDetails.Id -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    if ($FailOnErrorMessage -and $ackResponse.ErrorMessage) {\n        $messageString = \"The request against LCS succeeded, but the response was an error message for the operation: <c='em'>$($ackResponse.ErrorMessage)</c>.\"\n        $errorMessagePayload = \"`r`n$($ackResponse | ConvertTo-Json)\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $ackResponse\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $ackResponse\n    }\n\n    Write-PSFMessage -Level Verbose -Message \"Commit response\" -Target $ackResponse\n\n    Invoke-TimeSignal -End\n\n    [PSCustomObject]@{\n        AssetId  = $blobDetails.Id\n        Name     = $Name\n        Filename = $Filename\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365modulecompile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Compile a package / module / model\n        \n    .DESCRIPTION\n        Compile a package / module / model using the builtin \"xppc.exe\" executable to compile source code\n        \n    .PARAMETER Module\n        The package to compile\n        \n    .PARAMETER OutputDir\n        The path to the folder to save generated artifacts\n        \n    .PARAMETER LogPath\n        Path where you want to store the log outputs generated from the compiler\n        \n        Also used as the path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER ReferenceDir\n        The full path of a folder containing all assemblies referenced from X++ code\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER XRefSqlServer\n        The name of the SQL server where the cross references database is located; the default is \"$env:COMPUTERNAME\"\n        This parameter is only used for XRefGenerationOnly\n        \n    .PARAMETER XRefDbName\n        The name of the cross references database; the default is \"DYNAMICSXREFDB\"\n        This parameter is only used for XRefGenerationOnly\n        \n    .PARAMETER XRefGeneration\n        Instruct the cmdlet to enable the generation of XRef metadata while running the compile\n        \n    .PARAMETER XRefGenerationOnly\n        Instruct the cmdlet to only generate XRef metadata while running the compile and not update the assemblies and PDB files\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365ModuleCompile -Module MyModel\n        \n        This will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package.\n        The default output from the compile will be silenced.\n        \n        If an error should occur, both the standard output and error output will be written to the console / host.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365ModuleCompile -Module MyModel -ShowOriginalProgress\n        \n        This will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package.\n        The output from the compile will be written to the console / host.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365ModuleCompile -Module MyModel -XRefGeneration\n        \n        This will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package.\n        The default output from the compile will be silenced.\n        The compiler will generate XRef metadata while compiling.\n        \n        If an error should occur, both the standard output and error output will be written to the console / host.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365ModuleCompile -Module MyModel -XRefGenerationOnly\n        \n        This will use the default paths and start the xppc.exe with the needed parameters to only generate cross references for the MyModel package.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Module -ExcludeBinaryModules -InDependencyOrder | Invoke-D365ModuleCompile -XRefGenerationOnly -ShowOriginalProgress\n        \n        This will update all cross references, keeping the assemblies and PDB files unmodified.\n        The output from the compile will be written to the console / host.\n        \n    .NOTES\n        Tags: Compile, Model, Servicing, X++\n        \n        Author: Ievgen Miroshnikov (@IevgenMir)\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        Author: Frank Hüther (@FrankHuether)\n#>\n\nfunction Invoke-D365ModuleCompile {\n    [CmdletBinding()]\n    [OutputType('[PsCustomObject]')]\n    param (\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]\n        [Alias(\"ModuleName\")]\n        [string] $Module,\n\n        [Alias('Output')]\n        [string] $OutputDir = $Script:MetaDataDir,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModuleCompile\"),\n\n        [string] $MetaDataDir = $Script:MetaDataDir,\n\n        [string] $ReferenceDir = $Script:MetaDataDir,\n\n        [string] $BinDir = $Script:BinDirTools,\n\n        [string] $XRefSqlServer = $env:COMPUTERNAME,\n\n        [string] $XRefDbName = \"DYNAMICSXREFDB\",\n\n        [switch] $XRefGeneration,\n\n        [switch] $XRefGenerationOnly,\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n\n        $tool = \"xppc.exe\"\n        $executable = Join-Path -Path $BinDir -ChildPath $tool\n\n        if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { return }\n        if (-not (Test-PathExists -Path $executable -Type Leaf)) { return }\n        if (-not (Test-PathExists -Path $LogPath -Type Container -Create)) { return }\n\n    }\n\n    process {\n        $logDirModule = Join-Path -Path $LogPath -ChildPath $Module\n        $outputDirModule = Join-Path -Path $OutputDir -ChildPath $Module\n        \n        if (-not (Test-PathExists -Path $logDirModule -Type Container -Create)) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        $logFile = Join-Path -Path $logDirModule -ChildPath \"Dynamics.AX.$Module.xppc.log\"\n        $logXmlFile = Join-Path -Path $logDirModule -ChildPath \"Dynamics.AX.$Module.xppc.xml\"\n\n        $params = @(\"-metadata=`\"$MetaDataDir`\"\",\n            \"-modelmodule=`\"$Module`\"\",\n            \"-output=`\"$outputDirModule\\bin`\"\",\n            \"-referencefolder=`\"$ReferenceDir`\"\",\n            \"-log=`\"$logFile`\"\",\n            \"-xmlLog=`\"$logXmlFile`\"\",\n            \"-verbose\"\n        )\n\n        if ($XRefGenerationOnly) {\n            $params += @(\"-xrefonly\",\n                \"-xrefSqlServer=`\"$XRefSqlServer`\"\",\n                \"-xrefDbName=`\"$XRefDbName`\"\"\n            )\n        }\n        elseif ($XRefGeneration) {\n            $params += \"-xref\"\n        }\n\n        Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $logDirModule\n\n        if ($OutputCommandOnly) { return }\n\n        [PSCustomObject]@{\n            LogFile    = $logFile\n            XmlLogFile = $logXmlFile\n            PSTypeName = 'D365FO.TOOLS.ModuleCompileOutput'\n        }\n    \n    }\n\n    end {\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365modulefullcompile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Compile a package\n        \n    .DESCRIPTION\n        Compile a package using the builtin \"xppc.exe\" executable to compile source code, \"labelc.exe\" to compile label files and \"reportsc.exe\" to compile reports\n        \n    .PARAMETER Module\n        The package to compile\n        \n    .PARAMETER OutputDir\n        The path to the folder to save assemblies\n        \n    .PARAMETER LogPath\n        Path where you want to store the log outputs generated from the compiler\n        \n        Also used as the path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n    .PARAMETER ReferenceDir\n        The full path of a folder containing all assemblies referenced from X++ code\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365ModuleFullCompile -Module MyModel\n        \n        This will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package.\n        The default output from all the different steps will be silenced.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365ModuleFullCompile -Module MyModel -ShowOriginalProgress\n        \n        This will use the default paths and start the xppc.exe with the needed parameters to copmile MyModel package.\n        The default output from the different steps will be written to the console / host.\n        \n    .NOTES\n        Tags: Compile, Model, Servicing\n        \n        Author: Ievgen Miroshnikov (@IevgenMir)\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Invoke-D365ModuleFullCompile {\n    [CmdletBinding()]\n    [OutputType('[PsCustomObject]')]\n    param (\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]\n        [Alias(\"ModuleName\")]\n        [string] $Module,\n\n        [Alias('Output')]\n        [string] $OutputDir = $Script:MetaDataDir,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModuleCompile\"),\n\n        [string] $MetaDataDir = $Script:MetaDataDir,\n\n        [string] $ReferenceDir = $Script:MetaDataDir,\n\n        [string] $BinDir = $Script:BinDirTools,\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly\n    )\n\n    begin {\n\n        Invoke-TimeSignal -Start\n\n        if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { return }\n        if (-not (Test-PathExists -Path $LogPath -Type Container -Create)) { return }\n    }\n\n    process {\n        $resModuleCompile = Invoke-D365ModuleCompile @PSBoundParameters\n\n        $resLabelGeneration = Invoke-D365ModuleLabelGeneration @PSBoundParameters\n\n        $resReportsCompile = Invoke-D365ModuleReportsCompile @PSBoundParameters\n    \n        $resModuleCompile\n\n        $resLabelGeneration\n\n        $resReportsCompile\n    }\n\n    end {\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365modulelabelgeneration.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate labels for a package / module / model\n        \n    .DESCRIPTION\n        Generate labels for a package / module / model using the builtin \"labelc.exe\"\n        \n    .PARAMETER Module\n        Name of the package that you want to work against\n        \n    .PARAMETER OutputDir\n        The path to the folder to save generated artifacts\n        \n    .PARAMETER LogPath\n        Path where you want to store the log outputs generated from the compiler\n        \n        Also used as the path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER ReferenceDir\n        The full path of a folder containing all assemblies referenced from X++ code\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365ModuleLabelGeneration -Module MyModel\n        \n        This will use the default paths and start the labelc.exe with the needed parameters to labels from the MyModel package.\n        The default output from the generation process will be silenced.\n        \n        If an error should occur, both the standard output and error output will be written to the console / host.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365ModuleLabelGeneration -Module MyModel -ShowOriginalProgress\n        \n        This will use the default paths and start the labelc.exe with the needed parameters to labels from the MyModel package.\n        The output from the compile will be written to the console / host.\n        \n    .NOTES\n        Tags: Compile, Model, Servicing, Label, Labels\n        \n        Author: Ievgen Miroshnikov (@IevgenMir)\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Invoke-D365ModuleLabelGeneration {\n    [CmdletBinding()]\n    [OutputType('[PsCustomObject]')]\n    param (\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]\n        [Alias(\"ModuleName\")]\n        [string] $Module,\n\n        [Alias('Output')]\n        [string] $OutputDir = $Script:MetaDataDir,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModuleCompile\"),\n\n        [string] $MetaDataDir = $Script:MetaDataDir,\n\n        [string] $ReferenceDir = $Script:MetaDataDir,\n\n        [string] $BinDir = $Script:BinDirTools,\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n\n        $tool = \"labelc.exe\"\n        $executable = Join-Path -Path $BinDir -ChildPath $tool\n\n        if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { return }\n        if (-not (Test-PathExists -Path $executable -Type Leaf)) { return }\n        if (-not (Test-PathExists -Path $LogPath -Type Container -Create)) { return }\n    }\n\n    process {\n        $logDirModule = Join-Path -Path $LogPath -ChildPath $Module\n        $outputDirModule = Join-Path -Path $OutputDir -ChildPath $Module\n        \n        if (-not (Test-PathExists -Path $logDirModule -Type Container -Create)) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        $logFile = Join-Path -Path $logDirModule -ChildPath \"Dynamics.AX.$Module.labelc.log\"\n        $logErrorFile = Join-Path -Path $logDirModule -ChildPath \"Dynamics.AX.$Module.labelc.err\"\n  \n        $params = @(\"-metadata=`\"$MetaDataDir`\"\",\n            \"-modelmodule=`\"$Module`\"\",\n            \"-output=`\"$outputDirModule\\Resources`\"\",\n            \"-outlog=`\"$logFile`\"\",\n            \"-errlog=`\"$logErrorFile`\"\"\n        )\n    \n        Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $logDirModule\n\n        if ($OutputCommandOnly) { return }\n        \n        [PSCustomObject]@{\n            OutLogFile   = $logFile\n            ErrorLogFile = $logErrorFile\n            PSTypeName   = 'D365FO.TOOLS.ModuleLabelGenerationOutput'\n        }\n    }\n\n    end {\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365modulereportscompile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate reports for a package / module / model\n        \n    .DESCRIPTION\n        Generate reports for a package / module / model using the builtin \"ReportsC.exe\"\n        \n    .PARAMETER Module\n        Name of the package that you want to work against\n        \n    .PARAMETER OutputDir\n        The path to the folder to save generated artifacts\n        \n    .PARAMETER LogPath\n        Path where you want to store the log outputs generated from the compiler\n        \n        Also used as the path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER ReferenceDir\n        The full path of a folder containing all assemblies referenced from X++ code\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365ModuleReportsCompile -Module MyModel\n        \n        This will use the default paths and start the ReportsC.exe with the needed parameters to compile the reports from the MyModel package.\n        The default output from the reports compile will be silenced.\n        \n        If an error should occur, both the standard output and error output will be written to the console / host.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365ModuleReportsCompile -Module MyModel -ShowOriginalProgress\n        \n        This will use the default paths and start the ReportsC.exe with the needed parameters to compile the reports from the MyModel package.\n        The output from the compile will be written to the console / host.\n        \n    .NOTES\n        Tags: Compile, Model, Servicing, Report, Reports\n        \n        Author: Ievgen Miroshnikov (@IevgenMir)\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Invoke-D365ModuleReportsCompile {\n    [CmdletBinding()]\n    [OutputType('[PsCustomObject]')]\n    param (\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]\n        [Alias(\"ModuleName\")]\n        [string] $Module,\n\n        [Alias('Output')]\n        [string] $OutputDir = $Script:MetaDataDir,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModuleCompile\"),\n\n        [string] $MetaDataDir = $Script:MetaDataDir,\n\n        [string] $ReferenceDir = $Script:MetaDataDir,\n\n        [string] $BinDir = $Script:BinDirTools,\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n\n        $tool = \"ReportsC.exe\"\n        $executable = Join-Path -Path $BinDir -ChildPath $tool\n\n        if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { return }\n        if (-not (Test-PathExists -Path $executable -Type Leaf)) { return }\n        if (-not (Test-PathExists -Path $LogPath -Type Container -Create)) { return }\n    }\n    \n    process {\n        $logDirModule = Join-Path -Path $LogPath -ChildPath $Module\n        $outputDirModule = Join-Path -Path $OutputDir -ChildPath $Module\n        \n        if (-not (Test-PathExists -Path $logDirModule -Type Container -Create)) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        $logFile = Join-Path -Path $logDirModule -ChildPath \"Dynamics.AX.$Module.ReportsC.log\"\n        $logXmlFile = Join-Path -Path $logDirModule -ChildPath \"Dynamics.AX.$Module.ReportsC.xml\"\n\n        $params = @(\"-metadata=`\"$MetaDataDir`\"\",\n            \"-modelmodule=`\"$Module`\"\",\n            \"-LabelsPath=`\"$MetaDataDir`\"\",\n            \"-output=`\"$outputDirModule\\Reports`\"\",\n            \"-log=`\"$logFile`\"\",\n            \"-xmlLog=`\"$logXmlFile`\"\"\n        )\n\n        Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $logDirModule\n\n        if ($OutputCommandOnly) { return }\n\n        [PSCustomObject]@{\n            LogFile    = $logFile\n            XmlLogFile = $logXmlFile\n            PSTypeName = 'D365FO.TOOLS.ModuleReportsCompileOutput'\n        }\n    }\n\n    end {\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365processmodule.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Process a specific or multiple modules (compile, deploy reports and sync)\n        \n    .DESCRIPTION\n        Process a specific or multiple modules by invoking the following functions (based on flags)\n        - Invoke-D365ModuleFullCompile function\n        - Publish-D365SsrsReport to deploy the reports of a module\n        - Invoke-D365DBSyncPartial to sync the table and extension elements for module\n        \n    .PARAMETER Module\n        Name of the module that you want to process\n        \n        Accepts wildcards for searching. E.g. -Module \"Application*Adaptor\"\n        \n        Default value is \"*\" which will search for all modules\n        \n    .PARAMETER ExecuteCompile\n        Switch/flag to determine if the compile function should be executed for requested modules\n        \n    .PARAMETER ExecuteSync\n        Switch/flag to determine if the databasesync function should be executed for requested modules\n        \n    .PARAMETER ExecuteDeployReports\n        Switch/flag to determine if the deploy reports function should be executed for requested modules\n        \n    .PARAMETER OutputDir\n        The path to the folder to save assemblies\n        \n    .PARAMETER LogPath\n        Path where you want to store the log outputs generated from the compiler\n        \n        Also used as the path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n    .PARAMETER ReferenceDir\n        The full path of a folder containing all assemblies referenced from X++ code\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365ProcessModule -Module \"Application*Adaptor\" -ExecuteCompile\n        \n        Retrieve the list of installed packages / modules where the name fits the search \"Application*Adaptor\".\n        \n        For every value of the list perform the following:\n        * Invoke-D365ModuleFullCompile with the needed parameters to compile current module value package.\n        \n        The default output from all the different steps will be silenced.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365ProcessModule -Module \"Application*Adaptor\" -ExecuteSync\n        \n        Retrieve the list of installed packages / modules where the name fits the search \"Application*Adaptor\".\n        \n        For every value of the list perform the following:\n        * Invoke-D365DBSyncPartial with the needed parameters to sync current module value table and extension elements.\n        \n        The default output from all the different steps will be silenced.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365ProcessModule -Module \"Application*Adaptor\" -ExecuteDeployReports\n        \n        Retrieve the list of installed packages / modules where the name fits the search \"Application*Adaptor\".\n        \n        For every value of the list perform the following:\n        * Publish-D365SsrsReport with the required parameters to deploy all reports of current module\n        \n        The default output from all the different steps will be silenced.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365ProcessModule -Module \"Application*Adaptor\" -ExecuteCompile -ExecuteSync -ExecuteDeployReports\n        \n        Retrieve the list of installed packages / modules where the name fits the search \"Application*Adaptor\".\n        \n        For every value of the list perform the following:\n        * Invoke-D365ModuleFullCompile with the needed parameters to compile current module package.\n        * Invoke-D365DBSyncPartial with the needed parameters to sync current module table and extension elements.\n        * Publish-D365SsrsReport with the required parameters to deploy all reports of current module\n        \n        The default output from all the different steps will be silenced.\n        \n    .NOTES\n        Tags: Compile, Model, Servicing, Database, Synchronization\n        \n        Author: Jasper Callens - Cegeka\n#>\n\nfunction Invoke-D365ProcessModule {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [Alias(\"ModuleName\")]\n        [string] $Module,\n\n        [switch] $ExecuteCompile = $false,\n\n        [switch] $ExecuteSync = $false,\n\n        [switch] $ExecuteDeployReports = $false,\n\n        [Alias('Output')]\n        [string] $OutputDir = $Script:MetaDataDir,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModuleCompile\"),\n\n        [string] $MetaDataDir = $Script:MetaDataDir,\n\n        [string] $ReferenceDir = $Script:MetaDataDir,\n\n        [string] $BinDir = $Script:BinDirTools,\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n    }\n\n    process {\n        # Only execute the code if any of the flags are set\n        if ($ExecuteCompile -or $ExecuteSync -or $ExecuteDeployReports) {\n            # Retrieve all modules that match provided $Module\n            $moduleResults = Get-D365Module -Name $Module\n\n            # Output information on which modules that will be compiled and synced\n            Write-PSFMessage -Level Host -Message \"Modules to process: \"\n            $moduleResults | ForEach-Object {\n                Write-PSFMessage -Level Host -Message \" - $($_.Module) \"\n            }\n\n            # Empty list for all modules that have to be compiled\n            $modulesToCompile = @()\n            \n            # Empty list for all modules of which the reports have to be deployed\n            $modulesToDeployReports = @()\n\n            # Create empty lists for all sync-base and sync-extension elements\n            $syncList = @()\n            $syncExtensionsList = @()\n\n            # Loop every resulting module result and fill the required 'processing' lists based on the flags\n            foreach ($moduleElement in $moduleResults) {\n                if ($ExecuteCompile) {\n                    $modulesToCompile += $moduleElement\n                }\n\n                if ($ExecuteDeployReports) {\n                    $modulesToDeployReports += $moduleElement\n                }\n\n                if ($ExecuteSync) {\n                    # Retrieve the sync element of current module\n                    $moduleSyncElements = Get-SyncElements -ModuleName $moduleElement.Module\n\n                    # Add base and extensions elements to the sync lists\n                    $syncList += $moduleSyncElements.BaseSyncElements\n                    $syncExtensionsList += $moduleSyncElements.ExtensionSyncElements\n                }\n            }\n\n            if ($ExecuteCompile) {\n                # Loop over every module to compile and execute compile function\n                foreach ($moduleToCompile in $modulesToCompile) {\n                    # Build parameters for the full compile function\n                    $fullCompileParams = @{\n                        Module               = $moduleToCompile.Module;\n                        OutputDir            = $OutputDir;\n                        LogPath              = $LogPath;\n                        MetaDataDir          = $MetaDataDir;\n                        ReferenceDir         = $ReferenceDir;\n                        BinDir               = $BinDir;\n                        ShowOriginalProgress = $ShowOriginalProgress;\n                        OutputCommandOnly    = $OutputCommandOnly\n                    }\n\n                    # Call the full compile using required parameters\n                    $resModuleCompileFull = Invoke-D365ModuleFullCompile @fullCompileParams\n\n                    # Output results of full compile\n                    $resModuleCompileFull\n                }\n            }\n            \n            if ($ExecuteDeployReports) {\n                # Loop over every module to deploy reports and execute deploy report function\n                foreach ($moduleToDeployReports in $modulesToDeployReports) {\n                    # Build parameters for the model report deployment\n                    $fullDeployParams = @{\n                        Module  = $moduleToDeployReports.Module;\n                        LogFile = \"$LogPath\\$($moduleToDeployReports.Module).log\";\n                    }\n                    \n                    if ($OutputCommandOnly) {\n                        Write-PSFMessage -Level Host -Message \"Publish-D365SsrsReport $($fullDeployParams -join ' ')\"\n                    }\n                    else {\n                        $resModuleDeployReports = Publish-D365SsrsReport @fullDeployParams\n                        $resModuleDeployReports\n                    }\n                }\n            }\n\n            if ($ExecuteSync) {\n                # Build parameters for the partial sync function\n                $syncParams = @{\n                    SyncList             = $syncList;\n                    SyncExtensionsList   = $syncExtensionsList;\n                    BinDirTools          = $BinDir;\n                    MetadataDir          = $MetaDataDir;\n                    ShowOriginalProgress = $ShowOriginalProgress;\n                    OutputCommandOnly    = $OutputCommandOnly\n                }\n\n                # Call the partial sync using required parameters\n                $resSyncModule = Invoke-D365DBSyncPartial @syncParams\n                $resSyncModule\n            }\n        }\n        else {\n            Write-PSFMessage -Level Output -Message \"No process flags were set. Nothing will be processed\"\n        }\n    }\n\n    end {\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365rearmwindows.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Invokes the Rearm of Windows license\n        \n    .DESCRIPTION\n        Function used for invoking the rearm functionality inside Windows\n        \n    .PARAMETER Restart\n        Instruct the cmdlet to restart the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365ReArmWindows\n        \n        This will re arm the Windows installation if there is any activation retries left\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365ReArmWindows -Restart\n        \n        This will re arm the Windows installation if there is any activation retries left and restart the computer.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Invoke-D365ReArmWindows {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $false, Position = 1)]\n        [switch]$Restart\n    )\n\n    Write-PSFMessage -Level Verbose -Message \"Invoking the rearm process.\"\n\n    $instance = Get-CimInstance -Class SoftwareLicensingService -Namespace root/cimv2 -ComputerName .\n    Invoke-CimMethod -InputObject $instance -MethodName ReArmWindows\n    \n    if ($Restart) {\n        Restart-Computer -Force\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365runbookanalyzer.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Analyze the runbook\n        \n    .DESCRIPTION\n        Get all the important details from a failed runbook\n        \n    .PARAMETER Path\n        Path to the runbook file that you work against\n        \n    .PARAMETER FailedOnly\n        Instruct the cmdlet to only output failed steps\n        \n    .PARAMETER FailedOnlyAsObjects\n        Instruct the cmdlet to only output failed steps as objects\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365RunbookAnalyzer -Path \"C:\\DynamicsAX\\InstallationRecords\\Runbooks\\Runbook.xml\"\n        \n        This will analyze the Runbook.xml and output all the details about failed steps, the connected error logs and all the unprocessed steps.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer\n        \n        This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnly\n        \n        This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\n        The output from Invoke-D365RunbookAnalyzer will only contain failed steps.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnlyAsObjects\n        \n        This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\n        The output from Invoke-D365RunbookAnalyzer will only contain failed steps.\n        The output will be formatted as PSCustomObjects, to be used as variables or piping.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnlyAsObjects | Get-D365RunbookLogFile -Path \"C:\\Temp\\PU35\" -OpenInEditor\n        \n        This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\n        The output from Invoke-D365RunbookAnalyzer will only contain failed steps.\n        The Get-D365RunbookLogFile will open all log files for the failed step.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer | Out-File \"C:\\Temp\\d365fo.tools\\runbook-analyze-results.xml\"\n        \n        This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\n        The output will be saved into the \"C:\\Temp\\d365fo.tools\\runbook-analyze-results.xml\" file.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Runbook -Latest | Backup-D365Runbook -Force | Invoke-D365RunbookAnalyzer\n        \n        This will get the latest runbook from the default location.\n        This will backup the file onto the default \"c:\\temp\\d365fo.tools\\runbookbackups\\\".\n        This will start the Runbook Analyzer on the backup file.\n        \n    .NOTES\n        Tags: Runbook, Servicing, Hotfix, DeployablePackage, Deployable Package, InstallationRecordsDirectory, Installation Records Directory\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Invoke-D365RunbookAnalyzer {\n    [CmdletBinding(DefaultParameterSetName=\"Default\")]\n    [OutputType('System.String')]\n    param (\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true, ParameterSetName = \"Default\")]\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true, ParameterSetName = \"FailedOnly\")]\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true, ParameterSetName = \"FailedOnlyAsObjects\")]\n        [Alias('File')]\n        [string] $Path,\n\n        [Parameter(ParameterSetName = \"FailedOnly\")]\n        [switch] $FailedOnly,\n\n        [Parameter(ParameterSetName = \"FailedOnlyAsObjects\")]\n        [switch] $FailedOnlyAsObjects\n    )\n    \n    process {\n        if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n        $null = $sb = New-Object System.Text.StringBuilder\n        $null = $sb.AppendLine(\"<D365FO.Tools.Runbook.Analyzer.Output>\")\n\n        [xml]$xmlRunbook = Get-Content $Path\n\n        $failedObjs = New-Object System.Collections.Generic.List[System.Object]\n\n        $failedSteps = $xmlRunbook.SelectNodes(\"//RunbookStepList/Step/StepState[text()='Failed']\")\n\n        $failedSteps | ForEach-Object {\n            $null = $sb.AppendLine(\"<FailedStepInfo>\")\n\n            $stepId = $_.ParentNode | Select-Object -ExpandProperty childnodes | Where-Object { $_.name -like 'ID' } | Select-Object -ExpandProperty InnerText\n            $failedLogs = $xmlRunbook.SelectNodes(\"//RunbookLogs/Log/StepID[text()='$stepId']\")\n\n            $failedObjs.Add([PsCustomObject]@{Step = \"$stepId\" })\n\n            $null = $sb.AppendLine($_.ParentNode.OuterXml)\n\n            $failedLogs | ForEach-Object { $null = $sb.AppendLine( $_.ParentNode.OuterXml) }\n\n            $null = $sb.AppendLine(\"</FailedStepInfo>\")\n        }\n        \n        if ((-not $FailedOnly) -and (-not $FailedOnlyAsObjects)) {\n            $inProgressSteps = $xmlRunbook.SelectNodes(\"//RunbookStepList/Step/StepState[text()='InProgress']\")\n\n            $null = $sb.AppendLine(\"<InProgressStepInfo>\")\n\n            $inProgressSteps | ForEach-Object { $null = $sb.AppendLine( $_.ParentNode.OuterXml) }\n\n            $null = $sb.AppendLine(\"</InProgressStepInfo>\")\n\n            $unprocessedSteps = $xmlRunbook.SelectNodes(\"//RunbookStepList/Step/StepState[text()='NotStarted']\")\n\n            $null = $sb.AppendLine(\"<UnprocessedStepInfo>\")\n\n            $unprocessedSteps | ForEach-Object { $null = $sb.AppendLine( $_.ParentNode.OuterXml) }\n\n            $null = $sb.AppendLine(\"</UnprocessedStepInfo>\")\n        }\n\n        $null = $sb.AppendLine(\"</D365FO.Tools.Runbook.Analyzer.Output>\")\n\n        if ($FailedOnlyAsObjects) {\n            $failedObjs.ToArray()\n        }\n        else {\n            [xml]$xmlRaw = $sb.ToString()\n        \n            $stringWriter = New-Object System.IO.StringWriter;\n            $xmlWriter = New-Object System.Xml.XmlTextWriter $stringWriter;\n            $xmlWriter.Formatting = \"indented\";\n            $xmlRaw.WriteTo($xmlWriter);\n            $xmlWriter.Flush();\n            $stringWriter.Flush();\n            $stringWriter.ToString();\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365scdpbundleinstall.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Invoke the SCDPBundleInstall.exe file\n        \n    .DESCRIPTION\n        A cmdlet that wraps some of the cumbersome work of installing updates / hotfixes into a streamlined process\n        \n    .PARAMETER InstallOnly\n        Instructs the cmdlet to only run the Install option and ignore any TFS / VSTS folders and source control in general\n        \n        Use it when testing an update on a local development machine (VM) / onebox\n        \n    .PARAMETER Command\n        The command / job you want the cmdlet to execute\n        \n        Valid options are:\n        Prepare\n        Install\n        \n        Default value is \"Prepare\"\n        \n    .PARAMETER Path\n        Path to the update package that you want to install into the environment\n        \n        The cmdlet only supports an already extracted \".axscdppkg\" file\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER TfsWorkspaceDir\n        The path to the TFS Workspace directory that you want to work against\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER TfsUri\n        The URI for the TFS Team Site / VSTS Portal that you want to work against\n        \n        Default URI is the one that is configured from inside Visual Studio\n        \n    .PARAMETER ShowModifiedFiles\n        Switch to instruct the cmdlet to show all the modified files afterwards\n        \n    .PARAMETER ShowProgress\n        Switch to instruct the cmdlet to output progress details while servicing the installation\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SCDPBundleInstall -Path \"c:\\temp\\HotfixPackageBundle.axscdppkg\" -InstallOnly\n        \n        This will install the \"HotfixPackageBundle.axscdppkg\" into the default PackagesLocalDirectory location on the machine.\n        \n    .NOTES\n        Tags: Hotfix, Hotfixes, Updates, Prepare, VSTS, axscdppkg\n        \n        Author: Mötz Jensen (@splaxi)\n        \n        Author: Tommy Skaue (@skaue)\n#>\nfunction Invoke-D365SCDPBundleInstall {\n    [CmdletBinding(DefaultParameterSetName = 'InstallOnly')]\n    param (\n        [Parameter(Mandatory = $True, ParameterSetName = 'InstallOnly', Position = 0 )]\n        [switch] $InstallOnly,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Tfs', Position = 0 )]\n        [ValidateSet('Prepare', 'Install')]\n        [string] $Command = 'Prepare',\n\n        [Parameter(Mandatory = $True, Position = 1 )]\n        [Alias('Hotfix')]\n        [Alias('File')]\n        [string] $Path,\n\n        [Parameter(Mandatory = $False, Position = 2 )]\n        [string] $MetaDataDir = \"$Script:MetaDataDir\",\n\n        [Parameter(Mandatory = $False, ParameterSetName = 'Tfs', Position = 3 )]\n        [string] $TfsWorkspaceDir = \"$Script:MetaDataDir\",\n\n        [Parameter(Mandatory = $False, ParameterSetName = 'Tfs', Position = 4 )]\n        [string] $TfsUri = \"$Script:TfsUri\",\n\n        [Parameter(Mandatory = $False, Position = 4 )]\n        [switch] $ShowModifiedFiles,\n\n        [Parameter(Mandatory = $False, Position = 5 )]\n        [switch] $ShowProgress\n\n    )\n\n    if (!$script:IsAdminRuntime) {\n        Write-PSFMessage -Level Host -Message \"The cmdlet needs <c='em'>administrator permission</c> (Run As Administrator) to be able to update the configuration. Please start an <c='em'>elevated</c> session and run the cmdlet again.\"\n        Stop-PSFFunction -Message \"Stopping because the function is not run elevated\"\n        return\n    }\n\n    \n    Invoke-TimeSignal -Start\n    $StartTime = Get-Date\n    $executable = Join-Path $Script:BinDir \"\\bin\\SCDPBundleInstall.exe\"\n\n    if (!(Test-PathExists -Path $Path, $executable -Type Leaf)) { return }\n    if (!(Test-PathExists -Path $MetaDataDir -Type Container)) { return }\n    \n    Unblock-File -Path $Path #File is typically downloaded and extracted\n\n    if ($InstallOnly) {\n        $param = @(\"-install\",\n            \"-packagepath=$Path\",\n            \"-metadatastorepath=$MetaDataDir\")\n    }\n    else {\n\n        if ($TfsUri -eq \"\") {\n            Write-PSFMessage -Level Host -Message \"No TFS URI provided. Unable to complete the command.\"\n            Stop-PSFFunction -Message \"Stopping because missing TFS URI parameter.\"\n            return\n        }\n\n        switch ($Command) {\n            \"Prepare\" {\n                $param = @(\"-prepare\")\n            }\n            \"Install\" {\n                $param = @(\"-install\")\n            }\n        }\n        $param = $param + @(\"-packagepath=`\"$Path`\"\",\n            \"-metadatastorepath=`\"$MetaDataDir`\"\",\n            \"-tfsworkspacepath=`\"$TfsWorkspaceDir`\"\",\n            \"-tfsprojecturi=`\"$TfsUri`\"\")\n    }\n\n    Write-PSFMessage -Level Verbose -Message \"Invoking SCDPBundleInstall.exe with $Command\" -Target $param\n    \n    if ($ShowProgress) {\n        #! We should consider to redirect the standard output & error like this: https://stackoverflow.com/questions/8761888/capturing-standard-out-and-error-with-start-process\n        #Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly\n        $process = Start-Process -FilePath $executable -ArgumentList $param -PassThru\n\n        while (-not ($process.HasExited)) {\n            \n            $timeout = New-TimeSpan -Days 1\n            $stopwatch = [Diagnostics.StopWatch]::StartNew();\n            $bundleRoot = \"$env:localappdata\\temp\\SCDPBundleInstall\"\n            [xml]$manifest = Get-Content $(join-path $bundleRoot \"PackageDependencies.dgml\") -ErrorAction SilentlyContinue\n            $bundleCounter = 0\n            \n            if ($manifest) {\n                $bundleTotalCount = $manifest.DirectedGraph.Nodes.ChildNodes.Count\n            }\n            \n            while ($manifest -and (-not ($process.HasExited)) -and $stopwatch.elapsed -lt $timeout) {\n                $currentBundleFolder = Get-ChildItem $bundleRoot -Directory -ErrorAction SilentlyContinue\n        \n                if ($currentBundleFolder) {\n                    $currentBundle = $currentBundleFolder.Name\n        \n                    if ($announcedBundle -ne $currentBundle) {\n                        $announcedBundle = $currentBundle\n                        $bundleCounter = $bundleCounter + 1\n                        Write-PSFMessage -Level Verbose -Message \"$bundleCounter/$bundleTotalCount : Processing hotfix package $announcedBundle\"\n                    }\n                }\n            }\n            Start-Sleep -Milliseconds 100\n        }\n    }\n    else {\n        #! We should consider to redirect the standard output & error like this: https://stackoverflow.com/questions/8761888/capturing-standard-out-and-error-with-start-process\n        #Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly\n        Start-Process -FilePath $executable -ArgumentList $param -NoNewWindow -Wait\n    }\n    \n    if ($ShowModifiedFiles) {\n        $res = Get-ChildItem -Path $MetaDataDir -Recurse | Where-Object { $_.LastWriteTime -gt $StartTime }\n\n        $res | ForEach-Object {\n            Write-PSFMessage -Level Verbose -Message \"Object modified by the install: $($_.FullName)\"\n        }\n\n        $res\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365sdpinstall.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Install a Software Deployable Package (SDP)\n        \n    .DESCRIPTION\n        A cmdlet that wraps some of the cumbersome work into a streamlined process.\n        The process for a legacy (i.e. non unified) environment are detailed in the Microsoft documentation here:\n        https://docs.microsoft.com/en-us/dynamics365/unified-operations/dev-itpro/deployment/install-deployable-package\n        \n    .PARAMETER Path\n        Path to the update package that you want to install into the environment\n        \n        The cmdlet supports a path to a zip-file or directory with the unpacked contents.\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER QuickInstallAll\n        Use this switch to let the runbook reside in memory. You will not get a runbook on disc which you can examine for steps\n        \n    .PARAMETER DevInstall\n        Use this when running on developer box without administrator privileges (Run As Administrator)\n        \n    .PARAMETER Command\n        The command you want the cmdlet to execute when it runs the AXUpdateInstaller.exe\n        \n        Valid options are:\n        SetTopology\n        Generate\n        Import\n        Execute\n        RunAll\n        ReRunStep\n        SetStepComplete\n        Export\n        VersionCheck\n        \n        The default value is \"SetTopology\"\n        \n    .PARAMETER Step\n        The step number that you want to work against\n        \n    .PARAMETER RunbookId\n        The runbook id of the runbook that you want to work against\n        \n        Default value is \"Runbook\"\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .PARAMETER TopologyFile\n        Provide a custom topology file to use. By default, the cmdlet will use the DefaultTopologyData.xml file in the package directory.\n        \n    .PARAMETER UseExistingTopologyFile\n        Use this switch to indicate that the topology file is already updated and should not be updated again.\n        \n    .PARAMETER UnifiedDevelopmentEnvironment\n        Use this switch to install the package in a Unified Development Environment (UDE).\n        \n    .PARAMETER IncludeFallbackRetailServiceModels\n        Include fallback retail service models in the topology file\n        \n        This parameter is to support backward compatibility in this scenario:\n        Installing the first update on a local VHD where the information about the installed service\n        models may not be available and where the retail components are installed.\n        More information about this can be found at https://github.com/d365collaborative/d365fo.tools/issues/878\n        \n    .PARAMETER Force\n        Instruct the cmdlet to overwrite the \"extracted\" folder if it exists\n        \n        Used when the input is a zip file, that will auto extract to a folder named like the zip file.\n        \n    .PARAMETER ForceFallbackServiceModels\n        Force the use of the fallback list of known service model names\n        \n        This parameter supports update scenarios primarily on local VHDs where the information about\n        the installed service models may be incomplete. In such a case, the user receives a warning\n        and a suggestion to use this parameter.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SDPInstall -Path \"c:\\temp\\package.zip\" -QuickInstallAll\n        \n        This will install the package contained in the c:\\temp\\package.zip file using a runbook in memory while executing.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SDPInstall -Path \"c:\\temp\\\" -DevInstall\n        \n        This will install the extracted package in c:\\temp\\ using a runbook in memory while executing.\n        \n        This command is to be used on Microsoft Hosted Tier1 development environment, where you don't have access to the administrator user account on the vm.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command SetTopology\n        PS C:\\> Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command Generate -RunbookId 'MyRunbook'\n        PS C:\\> Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command Import -RunbookId 'MyRunbook'\n        PS C:\\> Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command Execute -RunbookId 'MyRunbook'\n        \n        Manual operations that first create Topology XML from current environment, then generate runbook with id 'MyRunbook', then import it and finally execute it.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RunAll\n        \n        Create Topology XML from current environment. Using default runbook id 'Runbook' and run all the operations from generate, to import to execute.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RerunStep -Step 18 -RunbookId 'MyRunbook'\n        \n        Rerun runbook with id 'MyRunbook' from step 18.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command SetStepComplete -Step 24 -RunbookId 'MyRunbook'\n        \n        Mark step 24 complete in runbook with id 'MyRunbook' and continue the runbook from the next step.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command SetTopology -TopologyFile \"c:\\temp\\MyTopology.xml\"\n        \n        Update the MyTopology.xml file with all the installed services on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RunAll -TopologyFile \"c:\\temp\\MyTopology.xml\" -UseExistingTopologyFile\n        \n        Run all manual steps in one single operation using the MyTopology.xml file. The topology file is not updated.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SDPInstall -Path \"c:\\temp\\\" -MetaDataDir \"c:\\MyRepository\\Metadata\" -UnifiedDevelopmentEnvironment\n        \n        Install the modules contained in the c:\\temp\\ directory into the c:\\MyRepository\\Metadata directory.\n        \n    .EXAMPLE\n        Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RunAll -IncludeFallbackRetailServiceModels\n        \n        Create Topology XML from current environment. If the current environment does not have the information about the installed service models, a fallback list of known service model names will be used.\n        This fallback list includes the retail service models.\n        Using default runbook id 'Runbook' and run all the operations from generate, to import to execute.\n        \n    .EXAMPLE\n        Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RunAll -ForceFallbackServiceModels\n        \n        Create Topology XML from current environment. If the current environment does have no or only partial information about the installed service models, a fallback list of known service model names will be used.\n        This fallback list does not include the retail service models.\n        Using default runbook id 'Runbook' and run all the operations from generate, to import to execute.\n        \n    .NOTES\n        Author: Tommy Skaue (@skaue)\n        Author: Mötz Jensen (@Splaxi)\n        Author: Florian Hopfner (@FH-Inway)\n        \n        Inspired by blogpost http://dev.goshoom.net/en/2016/11/installing-deployable-packages-with-powershell/\n        \n    .LINK\n        Invoke-D365SDPInstallUDE\n        \n#>\nfunction Invoke-D365SDPInstall {\n    [CmdletBinding(DefaultParameterSetName = 'QuickInstall')]\n    param (\n        [Parameter(Mandatory = $True, Position = 1 )]\n        [Alias('Hotfix')]\n        [Alias('File')]\n        [string] $Path,\n\n        [Parameter(Mandatory = $false, Position = 2 )]\n        [string] $MetaDataDir = \"$Script:MetaDataDir\",\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'QuickInstall', Position = 3 )]\n        [switch] $QuickInstallAll,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'DevInstall', Position = 3 )]\n        [switch] $DevInstall,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'Manual', Position = 3 )]\n        [ValidateSet('SetTopology', 'Generate', 'Import', 'Execute', 'RunAll', 'ReRunStep', 'SetStepComplete', 'Export', 'VersionCheck')]\n        [string] $Command = 'SetTopology',\n\n        [Parameter(Mandatory = $false, Position = 4 )]\n        [int] $Step,\n\n        [Parameter(Mandatory = $false, Position = 5 )]\n        [string] $RunbookId = \"Runbook\",\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\SdpInstall\"),\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly,\n\n        [string] $TopologyFile = \"DefaultTopologyData.xml\",\n\n        [switch] $UseExistingTopologyFile,\n\n        [Parameter(ParameterSetName = 'UDEInstall')]\n        [switch] $UnifiedDevelopmentEnvironment,\n\n        [switch] $IncludeFallbackRetailServiceModels,\n\n        [switch] $Force,\n\n        [switch] $ForceFallbackServiceModels\n    )\n\n    if ($UnifiedDevelopmentEnvironment) {\n        Invoke-D365SDPInstallUDE -Path $Path -MetaDataDir $MetaDataDir -LogPath $LogPath\n        return\n    }\n\n    if ((Get-Process -Name \"devenv\" -ErrorAction SilentlyContinue).Count -gt 0) {\n        Write-PSFMessage -Level Host -Message \"It seems that you have a <c='em'>Visual Studio</c> running. Please ensure <c='em'>exit</c> Visual Studio and run the cmdlet again.\"\n        Stop-PSFFunction -Message \"Stopping because of running Visual Studio.\"\n        return\n    }\n\n    Test-AssembliesLoaded\n\n    if (Test-PSFFunctionInterrupt) {\n        Write-PSFMessage -Level Host -Message \"It seems that you have executed some cmdlets that required to <c='em'>load</c> some Dynamics 356 Finance & Operations <c='em'>assemblies</c> into memory. Please <c='em'>close and restart</c> you PowerShell session / console, and <c='em'>start a fresh</c>. Please note that you should execute the failed command <c='em'>immediately</c> after importing the module.\"\n        Stop-PSFFunction -Message \"Stopping because of loaded assemblies.\"\n        return\n    }\n\n    $arrRunbookIds = Get-D365Runbook -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Get-D365RunbookId\n\n    if (($Command -eq \"RunAll\") -and ($arrRunbookIds.Runbookid -contains $RunbookId)) {\n        Write-PSFMessage -Level Host -Message \"It seems that you have entered an <c='em'>already used RunbookId</c>. Please consider if you are <c='em'>trying to re-run some steps</c> or simply pass <c='em'>another RunbookId</c>.\"\n        Stop-PSFFunction -Message \"Stopping because of RunbookId already used on this machine.\"\n        return\n    }\n\n    Invoke-TimeSignal -Start\n\n    #Test if input is a zipFile that needs to be extracted first\n    if ($Path.EndsWith(\".zip\")) {\n        Unblock-File -Path $Path\n\n        $extractedPath = $path.Remove($path.Length - 4)\n\n        if (-not $Force) {\n            if (-not (Test-PathExists -Path $extractedPath -Type Container -ShouldNotExist)) {\n                Write-PSFMessage -Level Host -Message \"The directory at the <c='em'>$extractedPath</c> location already exists. If you want to override it - set the <c='em'>Force</c> parameter to clear the folder and extract the content into it.\"\n                Stop-PSFFunction -Message \"Stopping because output path was already present.\"\n                return\n            }\n        }\n\n        Get-ChildItem -Path $extractedPath -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -Confirm:$false\n\n        # To allow the file system to flush the files\n        # Allows the human to see the folder being wiped\n        Start-Sleep -Seconds 2\n\n        Expand-Archive -Path $Path -DestinationPath $extractedPath -Force\n        $Path = $extractedPath\n    }\n\n    # Input is a relative path which needs to be converted to an absolute path.\n    # see https://powershellmagazine.com/2013/01/16/pstip-check-if-the-path-is-relative-or-absolute/\n    if (-not ([System.IO.Path]::IsPathRooted($Path) -or (Split-Path -Path $Path -IsAbsolute))) {\n        $currentPath = Get-Location\n        # https://stackoverflow.com/a/13847304/2720554\n        $absolutePath = Join-Path -Path $currentPath -ChildPath $Path\n        $absolutePath = [System.IO.Path]::GetFullPath($absolutePath)\n        Write-PSFMessage -Level Verbose \"Updating path to '$absolutePath' as relative paths are not supported\"\n        $Path = $absolutePath\n    }\n\n    $executable = Join-Path $Path \"AXUpdateInstaller.exe\"\n\n\n    if (-not ([System.IO.Path]::IsPathRooted($TopologyFile) -or (Split-Path -Path $TopologyFile -IsAbsolute))) {\n        $TopologyFile = Join-Path -Path $Path -ChildPath $TopologyFile\n    }\n\n    if (-not (Test-PathExists -Path $topologyFile, $executable -Type Leaf)) { return }\n\n    Get-ChildItem -Path $Path -Recurse | Unblock-File\n\n    if ($QuickInstallAll) {\n        Write-PSFMessage -Level Verbose \"Using QuickInstallAll mode\"\n        $params = \"quickinstallall\"\n\n        Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n    }\n    elseif ($DevInstall) {\n        Write-PSFMessage -Level Verbose \"Using DevInstall mode\"\n        $params = \"devinstall\"\n\n        Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n    }\n    else {\n        $Command = $Command.ToLowerInvariant()\n        $runbookFile = Join-Path $Path \"$runbookId.xml\"\n        $serviceModelFile = Join-Path $Path 'DefaultServiceModelData.xml'\n\n        if ($Command -eq 'runall') {\n            Write-PSFMessage -Level Verbose \"Running all manual steps in one single operation\"\n\n            #Update topology file (first command)\n            if (-not $UseExistingTopologyFile) {\n                $params = @{\n                    Path = $Path\n                    TopologyFile = $TopologyFile\n                    IncludeFallbackRetailServiceModels = $IncludeFallbackRetailServiceModels\n                    ForceFallbackServiceModels = $ForceFallbackServiceModels\n                }\n                $ok = Update-TopologyFile @params\n                if (-not $ok) {\n                    Write-PSFMessage -Level Warning \"Failed to update topology file.\"\n                    return\n                }\n            }\n\n            $params = @(\n                \"generate\"\n                \"-runbookId=`\"$runbookId`\"\"\n                \"-topologyFile=`\"$topologyFile`\"\"\n                \"-serviceModelFile=`\"$serviceModelFile`\"\"\n                \"-runbookFile=`\"$runbookFile`\"\"\n            )\n\n            #Generate (second command)\n            Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n\n            if (Test-PSFFunctionInterrupt) { return }\n\n            $params = @(\n                \"import\"\n                \"-runbookFile=`\"$runbookFile`\"\"\n            )\n\n            Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n\n            if (Test-PSFFunctionInterrupt) { return }\n\n            $params = @(\n                \"execute\"\n                \"-runbookId=`\"$runbookId`\"\"\n            )\n\n            Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n\n            if (Test-PSFFunctionInterrupt) { return }\n\n            Write-PSFMessage -Level Verbose \"All manual steps complete.\"\n        }\n        else {\n            $RunCommand = $true\n            switch ($Command) {\n                'settopology' {\n                    Write-PSFMessage -Level Verbose \"Updating topology file xml.\"\n\n                    if ($UseExistingTopologyFile) {\n                        Write-PSFMessage -Level Warning \"The SetTopology command is used to update a topology file. The UseExistingTopologyFile switch should not be used with this command.\"\n                        return\n                    }\n                    $params = @{\n                        Path = $Path\n                        TopologyFile = $TopologyFile\n                        IncludeFallbackRetailServiceModels = $IncludeFallbackRetailServiceModels\n                        ForceFallbackServiceModels = $ForceFallbackServiceModels\n                    }\n                    $ok = Update-TopologyFile @params\n                    if (-not $ok) {\n                        Write-PSFMessage -Level Warning \"Failed to update topology file.\"\n                    }\n                    $RunCommand = $false\n                }\n                'generate' {\n                    Write-PSFMessage -Level Verbose \"Generating runbook file.\"\n\n                    $params = @(\n                        \"generate\"\n                        \"-runbookId=`\"$runbookId`\"\"\n                        \"-topologyFile=`\"$topologyFile`\"\"\n                        \"-serviceModelFile=`\"$serviceModelFile`\"\"\n                        \"-runbookFile=`\"$runbookFile`\"\"\n                    )\n                }\n                'import' {\n                    Write-PSFMessage -Level Verbose \"Importing runbook file.\"\n\n                    $params = @(\n                        \"import\"\n                        \"-runbookfile=`\"$runbookFile`\"\"\n                    )\n                }\n                'execute' {\n                    Write-PSFMessage -Level Verbose \"Executing runbook file.\"\n\n                    $params = @(\n                        \"execute\"\n                        \"-runbookId=`\"$runbookId`\"\"\n                    )\n                }\n                'rerunstep' {\n                    Write-PSFMessage -Level Verbose \"Rerunning runbook step number $step.\"\n\n                    $params = @(\n                        \"execute\"\n                        \"-runbookId=`\"$runbookId`\"\"\n                        \"-rerunstep=$step\"\n                    )\n                }\n                'setstepcomplete' {\n                    Write-PSFMessage -Level Verbose \"Marking step $step complete and continuing from next step.\"\n\n                    $params = @(\n                        \"execute\"\n                        \"-runbookId=`\"$runbookId`\"\"\n                        \"-setstepcomplete=$step\"\n                    )\n                }\n                'export' {\n                    Write-PSFMessage -Level Verbose \"Exporting runbook for reuse.\"\n\n                    $params = @(\n                        \"export\"\n                        \"-runbookId=`\"$runbookId`\"\"\n                        \"-runbookfile=`\"$runbookFile`\"\"\n                    )\n                }\n                'versioncheck' {\n                    Write-PSFMessage -Level Verbose \"Running version check on runbook.\"\n\n                    $params = @(\n                        \"execute\"\n                        \"-runbookId=`\"$runbookId`\"\"\n                        \"-versioncheck=true\"\n                    )\n                }\n            }\n\n            if ($RunCommand) {\n                Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n\n                if (Test-PSFFunctionInterrupt) { return }\n            }\n        }\n    }\n\n    Invoke-TimeSignal -End\n\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365sdpinstallude.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Install a Software Deployable Package (SDP) in a unified development environment\n        \n    .DESCRIPTION\n        A cmdlet that wraps some of the cumbersome work into a streamlined process.\n        It first checks if the package is a zip file and extracts it if necessary.\n        Then it checks if the package contains the necessary files and modules.\n        Finally, it extracts the module zip files into the metadata directory.\n        \n    .PARAMETER Path\n        Path to the package that you want to install into the environment\n        \n        The cmdlet supports a path to a zip-file or directory with the unpacked contents.\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n    .PARAMETER Force\n        Instruct the cmdlet to overwrite the \"extracted\" folder if it exists\n        \n        Used when the input is a zip file, that will auto extract to a folder named like the zip file.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SDPInstallUDE -Path \"c:\\temp\\package.zip\" -MetaDataDir \"c:\\MyRepository\\Metadata\"\n        \n        This will install the modules contained in the c:\\temp\\package.zip file into the c:\\MyRepository\\Metadata directory.\n        \n    .NOTES\n        Author: Florian Hopfner (@FH-Inway)\n        \n#>\nfunction Invoke-D365SDPInstallUDE {\n    param (\n        [Parameter(Mandatory = $True, Position = 1 )]\n        [Alias('Hotfix')]\n        [Alias('File')]\n        [string] $Path,\n\n        [Parameter(Mandatory = $true, Position = 2 )]\n        [string] $MetaDataDir,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\SdpInstall\"),\n\n        [switch] $Force\n    )\n  \n    if ((Get-Process -Name \"devenv\" -ErrorAction SilentlyContinue).Count -gt 0) {\n        Write-PSFMessage -Level Host -Message \"It seems that you have a <c='em'>Visual Studio</c> running. Please ensure <c='em'>exit</c> Visual Studio and run the cmdlet again.\"\n        Stop-PSFFunction -Message \"Stopping because of running Visual Studio.\"\n        return\n    }\n\n    Invoke-TimeSignal -Start\n\n  \n    #Test if input is a zipFile that needs to be extracted first\n    if ($Path.EndsWith(\".zip\")) {\n        Unblock-File -Path $Path\n        \n        $extractedPath = $path.Remove($path.Length - 4)\n\n        if (-not $Force) {\n            if (-not (Test-PathExists -Path $extractedPath -Type Container -ShouldNotExist)) {\n                Write-PSFMessage -Level Host -Message \"The directory at the <c='em'>$extractedPath</c> location already exists. If you want to override it - set the <c='em'>Force</c> parameter to clear the folder and extract the content into it.\"\n                Stop-PSFFunction -Message \"Stopping because output path was already present.\"\n                return\n            }\n        }\n\n        Get-ChildItem -Path $extractedPath -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -Confirm:$false\n        \n        # To allow the file system to flush the files\n        # Allows the human to see the folder being wiped\n        Start-Sleep -Seconds 2\n\n        Expand-Archive -Path $Path -DestinationPath $extractedPath -Force\n        $Path = $extractedPath\n    }\n\n    # Input is a relative path which needs to be converted to an absolute path.\n    # see https://powershellmagazine.com/2013/01/16/pstip-check-if-the-path-is-relative-or-absolute/\n    if (-not ([System.IO.Path]::IsPathRooted($Path) -or (Split-Path -Path $Path -IsAbsolute))) {\n        $currentPath = Get-Location\n        # https://stackoverflow.com/a/13847304/2720554\n        $absolutePath = Join-Path -Path $currentPath -ChildPath $Path\n        $absolutePath = [System.IO.Path]::GetFullPath($absolutePath)\n        Write-PSFMessage -Level Verbose \"Updating path to '$absolutePath' as relative paths are not supported\"\n        $Path = $absolutePath\n    }\n    \n    Get-ChildItem -Path $Path -Recurse | Unblock-File\n    $packageDetails = Get-D365SDPDetails -Path $Path\n\n    $packagesFolder = \"$Path\\AOSService\\Packages\"\n    $filesFolder = Get-ChildItem -Path $packagesFolder -Directory -Filter \"files\"\n    if ($filesFolder.Count -eq 0) {\n        Write-PSFMessage -Level Host -Message \"No /AOSService/Packages/files folder found in the package. Please ensure that the package is extracted correctly.\"\n        Stop-PSFFunction -Message \"Stopping because of missing files folder.\"\n        return\n    }\n\n    $zipFiles = Get-ChildItem -Path $filesFolder.FullName -File -Filter \"*.zip\"\n    if ($zipFiles.Count -eq 0) {\n        Write-PSFMessage -Level Host -Message \"No module zip files found in the package. Please ensure that the package is extracted correctly.\"\n        Stop-PSFFunction -Message \"Stopping because of missing zip files.\"\n        return\n    }\n\n    $numberOfInstalledModules = 0\n    $packageDetails.Modules | ForEach-Object {\n        $moduleZip = $zipFiles | Where-Object Name -eq \"dynamicsax-$($_.Name).$($_.Version).zip\"\n        if (-not $moduleZip) {\n            Write-PSFMessage -Level Host -Message \"No module zip file found for module $($_.Name). Please ensure that the package is extracted correctly.\"\n            Stop-PSFFunction -Message \"Stopping because of missing module zip file.\"\n            return\n        }\n\n        # Delete existing module folder if it exists\n        $moduleFolderPath = Join-Path -Path $MetaDataDir -ChildPath $($_.Name)\n        if (Test-Path -Path $moduleFolderPath) {\n            Remove-Item -Path $moduleFolderPath -Recurse -Force\n            Write-PSFMessage -Level Verbose -Message \"Deleted existing module folder $moduleFolderPath\"\n        }\n\n        # Unzip to $MetaDataDir\n        $moduleZipPath = Join-Path -Path $MetaDataDir -ChildPath $($_.Name)\n        Expand-Archive -Path $moduleZip.FullName -DestinationPath $moduleZipPath\n        Write-PSFMessage -Level Verbose -Message \"Unzipped module $($_.Name) to $moduleZipPath\"\n        $numberOfInstalledModules++\n    }\n\n    Write-PSFMessage -Level Host -Message \"Installed $numberOfInstalledModules module(s) into $MetaDataDir\"\n\n    Invoke-TimeSignal -End\n  \n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365seleniumdownload.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Downloads the Selenium web driver files and deploys them to the specified destinations.\n        \n    .DESCRIPTION\n        Downloads the Selenium web driver files and deploys them to the specified destinations.\n        \n    .PARAMETER RegressionSuiteAutomationTool\n        Switch to specify if the Selenium files need to be installed in the Regression Suite Automation Tool folder.\n        \n    .PARAMETER PerfSDK\n        Switch to specify if the Selenium files need to be installed in the PerfSDK folder.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SeleniumDownload -RegressionSuiteAutomationTool -PerfSDK\n        \n        This will download the Selenium zip archives and extract the files into both the Regression Suite Automation Tool folder and the PerfSDK folder.\n        \n    .NOTES\n        Author: Kenny Saelen (@kennysaelen)\n        \n#>\n  function Invoke-D365SeleniumDownload\n  {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $false, Position = 0)]\n        [switch]$RegressionSuiteAutomationTool,\n        [Parameter(Mandatory = $false, Position = 1)]\n        [switch]$PerfSDK\n    )\n\n    if(!$RegressionSuiteAutomationTool -and !$PerfSDK)\n    {\n        Write-PSFMessage -Level Critical -Message \"Either the -RegressionSuiteAutomationTool or the -PerfSDK switch needs to be specified.\"\n        Stop-PSFFunction -Message \"Stopping because of no switch parameters speficied.\"\n        return\n    }\n    \n    $seleniumDllZipLocalPath = (Join-Path $env:TEMP \"selenium-dotnet-strongnamed-2.42.0.zip\")\n    $ieDriverZipLocalPath = (Join-Path $env:TEMP \"IEDriverServer_Win32_2.42.0.zip\")\n    $zipExtractionPath = (Join-Path $env:TEMP \"D365Seleniumextraction\")\n    \n    try\n    {\n        Write-PSFMessage -Level Host -Message \"Downloading Selenium files\"\n        \n        $WebClient = New-Object System.Net.WebClient\n        $WebClient.DownloadFile(\"http://selenium-release.storage.googleapis.com/2.42/selenium-dotnet-strongnamed-2.42.0.zip\", $seleniumDllZipLocalPath)\n        $WebClient.DownloadFile(\"http://selenium-release.storage.googleapis.com/2.42/IEDriverServer_Win32_2.42.0.zip\", $ieDriverZipLocalPath)\n\n        Write-PSFMessage -Level Host -Message \"Extracting zip files\"\n        Add-Type -AssemblyName System.IO.Compression.FileSystem\n        [System.IO.Compression.ZipFile]::ExtractToDirectory($seleniumDllZipLocalPath, $zipExtractionPath)\n        [System.IO.Compression.ZipFile]::ExtractToDirectory($ieDriverZipLocalPath, $zipExtractionPath)\n\n        $targetPath = [String]::Empty\n        $seleniumPath = [String]::Empty\n\n        if($RegressionSuiteAutomationTool)\n        {\n            Write-PSFMessage -Level Host -Message \"Making Selenium folder structure in the Regression Suite Automation Tool folder\"\n            $targetPath = Join-Path ([Environment]::GetEnvironmentVariable(\"ProgramFiles(x86)\")) \"Regression Suite Automation Tool\"\n            $seleniumPath = Join-Path $targetPath \"Common\\External\\Selenium\"\n\n            # Check if the Regression Suite Automation Tool is installed on the machine and Selenium not already installed\n            if (Test-PathExists -Path $targetPath -Type Container)\n            {\n                if(-not(Test-PathExists -Path $seleniumPath -Type Container -Create))\n                {\n                    Write-PSFMessage -Level Critical -Message [String]::Format(\"The folder for the Selenium files could not be created: {0}\", $seleniumPath)\n                }\n\n                Write-PSFMessage -Level Host -Message \"Copying Selenium files to destination folder\"\n                Copy-Item (Join-Path $zipExtractionPath \"IEDriverServer.exe\") $seleniumPath\n                Copy-Item (Join-Path $zipExtractionPath \"net40\\*\") $seleniumPath\n                Write-PSFMessage -Level Host -Message ([String]::Format(\"Selenium files have been downloaded and installed in the following folder: {0}\", $seleniumPath))\n            }\n            else\n            {\n                Write-PSFMessage -Level Warning -Message [String]::Format(\"The RegressionSuiteAutomationTool switch parameter is specified but the tool could not be located in the following folder: {0}\", $targetPath)\n            }\n        }\n        \n        if($PerfSDK)\n        {\n            Write-PSFMessage -Level Host -Message \"Making Selenium folder structure in the PerfSDK folder\"\n            $targetPath = [Environment]::GetEnvironmentVariable(\"PerfSDK\")\n            $seleniumPath = Join-Path $targetPath \"Common\\External\\Selenium\"\n\n            # Check if the PerfSDK is installed on the machine and Selenium not already installed\n            if (Test-PathExists -Path $targetPath -Type Container)\n            {\n                if(-not(Test-PathExists -Path $seleniumPath -Type Container -Create))\n                {\n                    Write-PSFMessage -Level Critical -Message [String]::Format(\"The folder for the Selenium files could not be created: {0}\", $seleniumPath)\n                }\n\n                Write-PSFMessage -Level Host -Message \"Copying Selenium files to destination folder\"\n                Copy-Item (Join-Path $zipExtractionPath \"IEDriverServer.exe\") $seleniumPath\n                Copy-Item (Join-Path $zipExtractionPath \"net40\\*\") $seleniumPath\n                Write-PSFMessage -Level Host -Message ([String]::Format(\"Selenium files have been downloaded and installed in the following folder: {0}\", $seleniumPath))\n            }\n            else\n            {\n                Write-PSFMessage -Level Warning -Message [String]::Format(\"The PerfSDK switch parameter is specified but the tool could not be located in the following folder: {0}\", $targetPath)\n            }\n        }\n    }\n    catch\n    {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while downloading and installing the Selenium files.\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n    finally\n    {\n        Write-PSFMessage -Level Host -Message \"Cleaning up temporary files\"\n        Remove-Item -Path $seleniumDllZipLocalPath -Recurse\n        Remove-Item -Path $ieDriverZipLocalPath -Recurse\n        Remove-Item -Path $zipExtractionPath -Recurse\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365sqlscript.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Execute a SQL Script or a SQL Command\n        \n    .DESCRIPTION\n        Execute a SQL Script or a SQL Command against the D365FO SQL Server database\n        \n    .PARAMETER FilePath\n        Path to the file containing the SQL Script that you want executed\n        \n    .PARAMETER Command\n        SQL command that you want executed\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER TrustedConnection\n        Switch to instruct the cmdlet whether the connection should be using Windows Authentication or not\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .PARAMETER NoPooling\n        Should the connection use connection pooling or not\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SqlScript -FilePath \"C:\\temp\\d365fo.tools\\DeleteUser.sql\"\n        \n        This will execute the \"C:\\temp\\d365fo.tools\\DeleteUser.sql\" against the registered SQL Server on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SqlScript -Command \"DELETE FROM SALESTABLE WHERE RECID = 123456789\"\n        \n        This will execute \"DELETE FROM SALESTABLE WHERE RECID = 123456789\" against the registered SQL Server on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SqlScript -Command \"DELETE FROM SALESTABLE WHERE RECID = 123456789\" -NoPooling\n        \n        This will execute \"DELETE FROM SALESTABLE WHERE RECID = 123456789\" against the registered SQL Server on the machine.\n        It will not use connection pooling.\n        \n    .NOTES\n        Author: Mötz Jensen (@splaxi)\n        \n        Author: Caleb Blanchard (@daxcaleb)\n#>\nFunction Invoke-D365SqlScript {\n    [Alias(\"Invoke-D365SqlCmd\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true, Position = 1, ParameterSetName = \"FilePath\" )]\n        [string] $FilePath,\n\n        [Parameter(Mandatory = $true, Position = 1, ParameterSetName = \"Command\" )]\n        [string] $Command,\n\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n        \n        [bool] $TrustedConnection = $false,\n\n        [switch] $EnableException,\n\n        [switch] $NoPooling\n\n    )\n\n    if ($PSCmdlet.ParameterSetName -eq \"FilePath\") {\n        if (-not (Test-PathExists -Path $FilePath -Type Leaf)) { return }\n    }\n\n    Invoke-TimeSignal -Start\n\n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n    $Params = @{}\n\n    #Hack to get all variables for the function, regardless of they were assigned from the caller or with default values.\n    #The TrustedConnection is the real deal breaker. If $true user and password are ignored in Get-SqlCommand.\n    $MyInvocation.MyCommand.Parameters.Keys | Get-Variable -ErrorAction Ignore | ForEach-Object { $Params.Add($_.Name, $_.Value) };\n    \n    $null = $Params.Remove('FilePath')\n    $null = $Params.Remove('Command')\n    $null = $Params.Remove('EnableException')\n    \n    $Params.TrustedConnection = $UseTrustedConnection\n\n    $sqlCommand = Get-SqlCommand @Params\n\n    if ($PSCmdlet.ParameterSetName -eq \"FilePath\") {\n        $sqlCommand.CommandText = (Get-Content \"$FilePath\") -join [Environment]::NewLine\n    }\n    if ($PSCmdlet.ParameterSetName -eq \"Command\") {\n        $sqlCommand.CommandText = $Command\n    }\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n\n        $null = $sqlCommand.ExecuteNonQuery()\n    }\n    catch {\n        $messageString = \"Something went wrong while <c='em'>executing custom sql script</c> against the database.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand)\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ -StepsUpward 1\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365sysflushaodcache.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Invoke the SysFlushAos class\n        \n    .DESCRIPTION\n        Invoke the runnable class SysFlushAos to clear the AOD cache\n        \n    .PARAMETER URL\n        URL to the Dynamics 365 instance you want to clear the AOD cache on\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SysFlushAodCache\n        \n        This will a call against the default URL for the machine and\n        have it execute the SysFlushAOD class\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Invoke-D365SysFlushAodCache {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $false, Position = 1 )]\n        [string] $Url\n    )\n\n    if ($PSBoundParameters.ContainsKey(\"URL\")) {\n        Invoke-D365SysRunnerClass -ClassName \"SysFlushAOD\" -Url $URL\n    }\n    else {\n        Invoke-D365SysRunnerClass -ClassName \"SysFlushAOD\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365sysrunnerclass.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Start a browser session that executes SysRunnerClass\n        \n    .DESCRIPTION\n        Makes it possible to call any runnable class directly from the browser, without worrying about the details\n        \n    .PARAMETER ClassName\n        The name of the class you want to execute\n        \n    .PARAMETER Company\n        The company for which you want to execute the class against\n        \n        Default value is: \"DAT\"\n        \n    .PARAMETER Url\n        The URL you want to execute against\n        \n        Default value is the Fully Qualified Domain Name registered on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SysRunnerClass -ClassName SysFlushAOD\n        \n        Will execute the SysRunnerClass and have it execute the SysFlushAOD class and will run it against the \"DAT\" (default value) company\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SysRunnerClass -ClassName SysFlushAOD -Company \"USMF\"\n        \n        Will execute the SysRunnerClass and have it execute the SysFlushAOD class and will run it against the \"USMF\" company\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365SysRunnerClass -ClassName SysFlushAOD -Url https://Test.cloud.onebox.dynamics.com\n        \n        Will execute the SysRunnerClass and have it execute the SysFlushAOD class and will run it against the \"DAT\" company, on the https://Test.cloud.onebox.dynamics.com URL\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Invoke-D365SysRunnerClass {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 1 )]\n        [string] $ClassName,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )]\n        \n        [string] $Company = $Script:Company,\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 3 )]\n        [string] $Url = $Script:Url\n    )\n\n    $executingUrl = \"$Url`?cmp=$Company&mi=SysClassRunner&cls=$ClassName\"\n    \n    Start-Process $executingUrl\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365tablebrowser.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Start a browser session that will show the table browser\n        \n    .DESCRIPTION\n        Makes it possible to call the table browser for a given table directly from the web browser, without worrying about the details\n        \n    .PARAMETER TableName\n        The name of the table you want to see the rows for\n        \n    .PARAMETER Company\n        The company for which you want to see the data from in the given table\n        \n        Default value is: \"DAT\"\n        \n    .PARAMETER Url\n        The URL you want to execute against\n        \n        Default value is the Fully Qualified Domain Name registered on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365TableBrowser -TableName SalesTable\n        \n        Will open the table browser and show all the records in Sales Table from the \"DAT\" company (default value).\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365TableBrowser -TableName SalesTable -Company \"USMF\"\n        \n        Will open the table browser and show all the records in Sales Table from the \"USMF\" company.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n        The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages.\n        \n#>\nfunction Invoke-D365TableBrowser {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 1 )]\n        [string] $TableName,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 2 )]\n        [string] $Company = $Script:Company,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 3 )]\n        [string] $Url = $Script:Url\n    )\n    BEGIN {}\n\n    PROCESS {\n        Write-PSFMessage -Level Verbose -Message \"Table name: $TableName\" -Target $TableName\n        $executingUrl = \"$Url`?cmp=$Company&mi=SysTableBrowser&tablename=$TableName\"\n\n        Start-Process $executingUrl\n\n        #* Allow the browser to start and process first request if it isn't running already\n        Start-Sleep -Seconds 1\n    }\n\n    END {}\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365visualstudiocompilerresultanalyzer.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Analyze the Visual Studio compiler output log\n        \n    .DESCRIPTION\n        Analyze the Visual Studio compiler output log and generate an excel file contain worksheets per type: Errors, Warnings, Tasks\n        \n    .PARAMETER Module\n        Name of the module that you want to work against\n        \n        Default value is \"*\" which will search for all modules\n        \n    .PARAMETER OutputPath\n        Path where you want the excel file (xlsx-file) saved to\n        \n        Default value is: \"c:\\temp\\d365fo.tools\\\"\n        \n    .PARAMETER SkipWarnings\n        Instructs the cmdlet to skip warnings while analyzing the compiler output log file\n        \n    .PARAMETER SkipTasks\n        Instructs the cmdlet to skip tasks while analyzing the compiler output log file\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Default path is the same as the AOS service \"PackagesLocalDirectory\" directory\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365VisualStudioCompilerResultAnalyzer\n        \n        This will analyse all compiler output log files generated from Visual Studio.\n        \n        A result set example:\n        \n        File                                                            Filename\n        ----                                                            --------\n        c:\\temp\\d365fo.tools\\ApplicationCommon-CompilerResults.xlsx     ApplicationCommon-CompilerResults.xlsx\n        c:\\temp\\d365fo.tools\\ApplicationFoundation-CompilerResults.xlsx ApplicationFoundation-CompilerResults.xlsx\n        c:\\temp\\d365fo.tools\\ApplicationPlatform-CompilerResults.xlsx   ApplicationPlatform-CompilerResults.xlsx\n        c:\\temp\\d365fo.tools\\ApplicationSuite-CompilerResults.xlsx      ApplicationSuite-CompilerResults.xlsx\n        c:\\temp\\d365fo.tools\\ApplicationWorkspaces-CompilerResults.xlsx ApplicationWorkspaces-CompilerResults.xlsx\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365VisualStudioCompilerResultAnalyzer -SkipWarnings\n        \n        This will analyse all compiler output log files generated from Visual Studio.\n        It will exclude all warnings from the output.\n        \n        A result set example:\n        \n        File                                                            Filename\n        ----                                                            --------\n        c:\\temp\\d365fo.tools\\ApplicationCommon-CompilerResults.xlsx     ApplicationCommon-CompilerResults.xlsx\n        c:\\temp\\d365fo.tools\\ApplicationFoundation-CompilerResults.xlsx ApplicationFoundation-CompilerResults.xlsx\n        c:\\temp\\d365fo.tools\\ApplicationPlatform-CompilerResults.xlsx   ApplicationPlatform-CompilerResults.xlsx\n        c:\\temp\\d365fo.tools\\ApplicationSuite-CompilerResults.xlsx      ApplicationSuite-CompilerResults.xlsx\n        c:\\temp\\d365fo.tools\\ApplicationWorkspaces-CompilerResults.xlsx ApplicationWorkspaces-CompilerResults.xlsx\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365VisualStudioCompilerResultAnalyzer -SkipTasks\n        \n        This will analyse all compiler output log files generated from Visual Studio.\n        It will exclude all tasks from the output.\n        \n        A result set example:\n        \n        File                                                            Filename\n        ----                                                            --------\n        c:\\temp\\d365fo.tools\\ApplicationCommon-CompilerResults.xlsx     ApplicationCommon-CompilerResults.xlsx\n        c:\\temp\\d365fo.tools\\ApplicationFoundation-CompilerResults.xlsx ApplicationFoundation-CompilerResults.xlsx\n        c:\\temp\\d365fo.tools\\ApplicationPlatform-CompilerResults.xlsx   ApplicationPlatform-CompilerResults.xlsx\n        c:\\temp\\d365fo.tools\\ApplicationSuite-CompilerResults.xlsx      ApplicationSuite-CompilerResults.xlsx\n        c:\\temp\\d365fo.tools\\ApplicationWorkspaces-CompilerResults.xlsx ApplicationWorkspaces-CompilerResults.xlsx\n        \n    .NOTES\n        Tags: Compiler, Build, Errors, Warnings, Tasks\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        This cmdlet is inspired by the work of \"Vilmos Kintera\" (twitter: @DAXRunBase)\n        \n        All credits goes to him for showing how to extract these information\n        \n        His blog can be found here:\n        https://www.daxrunbase.com/blog/\n        \n        The specific blog post that we based this cmdlet on can be found here:\n        https://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/\n        \n        The github repository containing the original scrips can be found here:\n        https://github.com/DAXRunBase/PowerShell-and-Azure\n#>\nfunction Invoke-D365VisualStudioCompilerResultAnalyzer {\n    [CmdletBinding()]\n    [OutputType('')]\n    param (\n        [Alias(\"ModuleName\")]\n        [string] $Module = \"*\",\n\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [switch] $SkipWarnings,\n\n        [switch] $SkipTasks,\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    Invoke-TimeSignal -Start\n\n    if (-not (Test-PathExists -Path $PackageDirectory -Type Container)) { return }\n    \n    $buildOutputFiles = Get-ChildItem -Path \"$PackageDirectory\\$Module\\BuildModelResult.log\" -ErrorAction SilentlyContinue -Force\n\n    foreach ($result in $buildOutputFiles) {\n        \n        $moduleName = Split-Path -Path $result.DirectoryName -Leaf\n        $outputFilePath = Join-Path -Path $OutputPath -ChildPath \"$moduleName-CompilerResults.xlsx\"\n\n        Invoke-CompilerResultAnalyzer -Path $result.FullName -Identifier $moduleName -OutputPath $outputFilePath -SkipWarnings:$SkipWarnings -SkipTasks:$SkipTasks -PackageDirectory $PackageDirectory\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/invoke-d365winrmcertificaterotation.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Rotate the certificate used for WinRM\n        \n    .DESCRIPTION\n        There is a scenario where you might need to update the certificate that is being used for WinRM on your Tier1 environment\n        \n        1 year after you deploy your Tier1 environment, the original WinRM certificate expires and then LCS will be unable to communicate with your Tier1 environment\n        \n    .PARAMETER MachineName\n        The DNS / Netbios name of the machine\n        \n        The default value is: \"$env:COMPUTERNAME\" which translates into the current name of the machine\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365WinRmCertificateRotation\n        \n        This will update the certificate that is being used by WinRM.\n        A new certificate is created with the current computer name.\n        The new certificate and its thumbprint will be configured for WinRM to use that going forward.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n        We recommend that you do a full restart of the Tier1 environment when done.\n        \n#>\nfunction Invoke-D365WinRmCertificateRotation {\n    [CmdletBinding()]\n    [OutputType()]\n    param(\n        [string] $MachineName = $env:COMPUTERNAME\n    )\n\n    Write-PSFMessage -Level Verbose \"Creating a new certificate.\"\n\n    $CertStore = \"Cert:\\LocalMachine\\My\"\n    $Thumbprint = (New-SelfSignedCertificate -DnsName $MachineName -CertStoreLocation $CertStore).Thumbprint\n\n    $executable = \"C:\\Windows\\System32\\cmd.exe\"\n\n    $params = @(\"/C\", \"winrm\", \"set\",\n        \"winrm/config/Listener?Address=*+Transport=HTTPS\",\n        \"@{Hostname=\"\"$DNSName\"\"; CertificateThumbprint=\"\"$Thumbprint\"\"}\"\n    )\n\n    Write-PSFMessage -Level Verbose \"Configure WinRM to use the newly created certificate.\"\n\n    Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$true\n}"
  },
  {
    "path": "d365fo.tools/functions/new-d365bacpac.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate a bacpac file from a database\n        \n    .DESCRIPTION\n        Takes care of all the details and steps that is needed to create a valid bacpac file to move between Tier 1 (onebox or Azure hosted) and Tier 2 (MS hosted), or vice versa\n        \n        Supports to create a raw bacpac file without prepping. Can be used to automate backup from Tier 2 (MS hosted) environment\n        \n    .PARAMETER ExportModeTier1\n        Switch to instruct the cmdlet that the export will be done against a classic SQL Server installation\n        \n    .PARAMETER ExportModeTier2\n        Switch to instruct the cmdlet that the export will be done against an Azure SQL DB instance\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER BackupDirectory\n        The path where to store the temporary backup file when the script needs to handle that\n        \n    .PARAMETER NewDatabaseName\n        The name for the database the script is going to create when doing the restore process\n        \n    .PARAMETER BacpacFile\n        The path where you want the cmdlet to store the bacpac file that will be generated\n        \n    .PARAMETER CustomSqlFile\n        The path to a custom sql server script file that you want executed against the database before it is exported\n        \n    .PARAMETER DiagnosticFile\n        Path to where you want the export to output a diagnostics file to assist you in troubleshooting the export\n        \n    .PARAMETER ExportOnly\n        Switch to instruct the cmdlet to either just create a dump bacpac file or run the prepping process first\n        \n    .PARAMETER MaxParallelism\n        Sets SqlPackage.exe's degree of parallelism for concurrent operations running against a database. The default value is 8.\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365InstallSqlPackage\n        \n        You should always install the latest version of the SqlPackage.exe, which is used by New-D365Bacpac.\n        \n        This will fetch the latest .Net Core Version of SqlPackage.exe and install it at \"C:\\temp\\d365fo.tools\\SqlPackage\".\n        \n    .EXAMPLE\n        PS C:\\> New-D365Bacpac -ExportModeTier1 -BackupDirectory c:\\Temp\\backup\\ -NewDatabaseName Testing1 -BacpacFile \"C:\\Temp\\Bacpac\\Testing1.bacpac\"\n        \n        Will backup the \"AXDB\" database and restore is as \"Testing1\" again the localhost SQL Server.\n        Will run the prepping process against the restored database.\n        Will export a bacpac file to \"C:\\Temp\\Bacpac\\Testing1.bacpac\".\n        Will delete the restored database.\n        It will use trusted connection (Windows authentication) while working against the SQL Server.\n        \n    .EXAMPLE\n        PS C:\\> New-D365Bacpac -ExportModeTier2 -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\" -NewDatabaseName Testing1 -BacpacFile C:\\Temp\\Bacpac\\Testing1.bacpac\n        \n        Will create a copy the db database on the dbserver1 in Azure.\n        Will run the prepping process against the copy database.\n        Will export a bacpac file.\n        Will delete the copy database.\n        \n    .EXAMPLE\n        PS C:\\> New-D365Bacpac -ExportModeTier2 -SqlUser User123 -SqlPwd \"Password123\" -NewDatabaseName Testing1 -BacpacFile \"C:\\Temp\\Bacpac\\Testing1.bacpac\"\n        \n        Normally used for a Tier-2 export and preparation for Tier-1 import\n        \n        Will create a copy of the registered D365 database on the registered D365 Azure SQL DB instance.\n        Will run the prepping process against the copy database.\n        Will export a bacpac file.\n        Will delete the copy database.\n        \n    .EXAMPLE\n        PS C:\\> New-D365Bacpac -ExportModeTier2 -SqlUser User123 -SqlPwd \"Password123\" -NewDatabaseName Testing1 -BacpacFile C:\\Temp\\Bacpac\\Testing1.bacpac -ExportOnly\n        \n        Will export a bacpac file.\n        The bacpac should be able to restore back into the database without any preparing because it is coming from the environment from the beginning\n        \n    .EXAMPLE\n        PS C:\\> New-D365Bacpac -ExportModeTier1 -BackupDirectory c:\\Temp\\backup\\ -NewDatabaseName Testing1 -BacpacFile \"C:\\Temp\\Bacpac\\Testing1.bacpac\" -DiagnosticFile \"C:\\temp\\ExportLog.txt\"\n        \n        Will backup the \"AXDB\" database and restore is as \"Testing1\" again the localhost SQL Server.\n        Will run the prepping process against the restored database.\n        Will export a bacpac file to \"C:\\Temp\\Bacpac\\Testing1.bacpac\".\n        Will delete the restored database.\n        It will use trusted connection (Windows authentication) while working against the SQL Server.\n        \n        It will output a diagnostic file to \"C:\\temp\\ExportLog.txt\".\n        \n    .EXAMPLE\n        PS C:\\> New-D365Bacpac -ExportModeTier1 -BackupDirectory c:\\Temp\\backup\\ -NewDatabaseName Testing1 -BacpacFile \"C:\\Temp\\Bacpac\\Testing1.bacpac\" -MaxParallelism 32\n        \n        Will backup the \"AXDB\" database and restore is as \"Testing1\" again the localhost SQL Server.\n        Will run the prepping process against the restored database.\n        Will export a bacpac file to \"C:\\Temp\\Bacpac\\Testing1.bacpac\".\n        Will delete the restored database.\n        It will use trusted connection (Windows authentication) while working against the SQL Server.\n        \n        It will use 32 connections against the database server while generating the bacpac file.\n        \n    .NOTES\n        The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages.\n        \n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction New-D365Bacpac {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseProcessBlockForPipelineCommand\", \"\")]\n    [CmdletBinding(DefaultParameterSetName = 'ExportTier2')]\n    param (\n        [Parameter(Mandatory = $true, ParameterSetName = 'ExportTier1', Position = 0)]\n        [switch] $ExportModeTier1,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'ExportTier2', Position = 0)]\n        [switch] $ExportModeTier2,\n\n        [Parameter(Position = 1 )]\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Position = 2 )]\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false, Position = 3 )]\n        [Parameter(Mandatory = $true, ParameterSetName = 'ExportTier2', ValueFromPipelineByPropertyName = $true, Position = 3)]\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false, Position = 4 )]\n        [Parameter(Mandatory = $true, ParameterSetName = 'ExportTier2', ValueFromPipelineByPropertyName = $true, Position = 4)]\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [Parameter(ParameterSetName = 'ExportTier1', Position = 5 )]\n        [string] $BackupDirectory = \"C:\\Temp\\d365fo.tools\\SqlBackups\",\n\n        [Parameter(Position = 6 )]\n        [string] $NewDatabaseName = \"$Script:DatabaseName`_export\",\n\n        [Parameter(Position = 7 )]\n        [Alias('File')]\n        [string] $BacpacFile = \"C:\\Temp\\d365fo.tools\\$DatabaseName.bacpac\",\n\n        [Parameter(Position = 8 )]\n        [string] $CustomSqlFile,\n\n        [string] $DiagnosticFile,\n\n        [switch] $ExportOnly,\n\n        [int] $MaxParallelism = 8,\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly,\n\n        [switch] $EnableException\n    )\n    \n    Invoke-TimeSignal -Start\n\n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n    \n    if ($PSBoundParameters.ContainsKey(\"CustomSqlFile\")) {\n        if (-not (Test-PathExists -Path $CustomSqlFile -Type Leaf)) { return }\n        $ExecuteCustomSQL = $true\n    }\n\n    if ($BacpacFile -notlike \"*.bacpac\") {\n        Write-PSFMessage -Level Host -Message \"The path for the bacpac file must contain the <c='em'>.bacpac</c> extension. Please update the <c='em'>BacpacFile</c> parameter and try again.\"\n        Stop-PSFFunction -Message \"The BacpacFile path was not correct.\"\n        return\n    }\n\n    if ($PSBoundParameters.ContainsKey(\"BackupDirectory\") -or $ExportModeTier1) {\n        if (-not (Test-PathExists -Path $BackupDirectory -Type Container -Create)) { return }\n    }\n    \n    if (-not (Test-PathExists -Path (Split-Path $BacpacFile -Parent) -Type Container -Create)) { return }\n\n    # Work around to make sure to keep Storage when using the non-core version of the SqlPackage\n    $executable = $Script:SqlPackagePath\n    $classicPattern = \"C:\\Program Files*\\Microsoft SQL Server\\1*0\\DAC\\bin\\SqlPackage.exe\"\n\n    [System.Collections.ArrayList] $Properties = New-Object -TypeName \"System.Collections.ArrayList\"\n\n    $null = $Properties.Add(\"VerifyFullTextDocumentTypesSupported=false\")\n\n    if($executable -like $classicPattern) {\n        Write-PSFMessage -Level Verbose -Message \"Looks like we are running against the non-core version of SqlPackage.exe. Then we need to support the Storage=File property.\"\n        $null = $Properties.Add(\"Storage=File\")\n    }\n\n    $BaseParams = @{\n        DatabaseServer = $DatabaseServer\n        DatabaseName   = $DatabaseName\n        SqlUser        = $SqlUser\n        SqlPwd         = $SqlPwd\n    }\n\n    $ExportParams = @{\n        Action     = \"export\"\n        FilePath   = $BacpacFile\n        Properties = $Properties.ToArray()\n        MaxParallelism = $MaxParallelism\n    }\n\n    if (-not [system.string]::IsNullOrEmpty($DiagnosticFile)) {\n        if (-not (Test-PathExists -Path (Split-Path $DiagnosticFile -Parent) -Type Container -Create)) { return }\n        $ExportParams.DiagnosticFile = $DiagnosticFile\n    }\n\n    if ($ExportOnly) {\n        \n        Write-PSFMessage -Level Verbose -Message \"Invoking the export of the bacpac file only.\"\n\n        Write-PSFMessage -Level Verbose -Message \"Invoking the sqlpackage with parameters\" -Target $BaseParams\n        Invoke-SqlPackage @BaseParams @ExportParams -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly\n\n        if ($OutputCommandOnly) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        [PSCustomObject]@{\n            File     = $BacpacFile\n            Filename = (Split-Path $BacpacFile -Leaf)\n        }\n    }\n    else {\n        if ($ExportModeTier1) {\n            $Params = @{\n                BackupDirectory   = $BackupDirectory\n                NewDatabaseName   = $NewDatabaseName\n                TrustedConnection = $UseTrustedConnection\n            }\n            \n            if (-not $OutputCommandOnly) {\n                Write-PSFMessage -Level Verbose -Message \"Invoking the Tier 1 - SQL backup & restore process\"\n                $res = Invoke-SqlBackupRestore @BaseParams @Params\n\n                if ((Test-PSFFunctionInterrupt) -or (-not $res)) { return }\n\n                $Params = Get-DeepClone $BaseParams\n                $Params.DatabaseName = $NewDatabaseName\n\n                Write-PSFMessage -Level Verbose -Message \"Invoking the Tier 1 - Clear SQL objects\"\n                $res = Invoke-ClearSqlSpecificObjects @Params\n\n                if ((Test-PSFFunctionInterrupt) -or (-not $res)) { return }\n\n                if ($ExecuteCustomSQL) {\n                    Write-PSFMessage -Level Verbose -Message \"Invoking the Tier 1 - Execution of custom SQL script\"\n                    $res = Invoke-D365SqlScript @Params -FilePath $CustomSqlFile\n\n                    if (Test-PSFFunctionInterrupt) { return }\n                }\n            }\n            else {\n                $Params = Get-DeepClone $BaseParams\n                $Params.DatabaseName = $NewDatabaseName\n            }\n\n            Write-PSFMessage -Level Verbose -Message \"Invoking the Tier 1 - Export of the bacpac file from SQL\"\n            Invoke-SqlPackage @Params @ExportParams -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly\n            \n            if ($OutputCommandOnly) { return }\n\n            if (Test-PSFFunctionInterrupt) { return }\n\n            Write-PSFMessage -Level Verbose -Message \"Invoking the Tier 1 - Remove database from SQL\"\n            Remove-D365Database @Params -Confirm:$false\n\n            [PSCustomObject]@{\n                File     = $BacpacFile\n                Filename = (Split-Path $BacpacFile -Leaf)\n            }\n        }\n        else {\n            $Params = @{\n                NewDatabaseName = $NewDatabaseName\n            }\n\n            if (-not $OutputCommandOnly) {\n                Write-PSFMessage -Level Verbose -Message \"Invoking the Tier 2 - Creation of Azure DB copy\"\n                $res = Invoke-AzureBackupRestore @BaseParams @Params\n            \n                if ((Test-PSFFunctionInterrupt) -or (-not $res)) { return }\n            \n                $Params = Get-DeepClone $BaseParams\n                $Params.DatabaseName = $NewDatabaseName\n                Write-PSFMessage -Level Verbose -Message \"Invoking the Tier 2 - Clear Azure DB objects\"\n                $res = Invoke-ClearAzureSpecificObjects @Params\n\n                if ((Test-PSFFunctionInterrupt) -or (-not $res)) { return }\n\n                if ($ExecuteCustomSQL) {\n                    Write-PSFMessage -Level Verbose -Message \"Invoking the Tier 2 - Execution of custom SQL script\"\n                    $res = Invoke-D365SqlScript @Params -FilePath $CustomSqlFile -TrustedConnection $false\n\n                    if (!$res) { return }\n                }\n            }\n\n            Write-PSFMessage -Level Verbose -Message \"Invoking the Tier 2 - Export of the bacpac file from Azure DB\"\n            Invoke-SqlPackage @Params @ExportParams -TrustedConnection $false -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly\n\n            if ($OutputCommandOnly) { return }\n\n            if (Test-PSFFunctionInterrupt) { return }\n            \n            Write-PSFMessage -Level Verbose -Message \"Invoking the Tier 2 - Remove database from Azure DB\"\n            Remove-D365Database @Params -Confirm:$false\n\n            if (Test-PSFFunctionInterrupt) {\n                $messageString = \"The bacpac file was created correctly, but there was an error while <c='em'>removing</c> the cloned database.\"\n                Write-PSFMessage -Level Host -Message $messageString\n            }\n\n            [PSCustomObject]@{\n                File     = $BacpacFile\n                Filename = (Split-Path $BacpacFile -Leaf)\n            }\n        }\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/new-d365careport.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Generate the Customization's Analysis Report (CAR)\n        \n    .DESCRIPTION\n        A cmdlet that wraps some of the cumbersome work into a streamlined process\n        \n    .PARAMETER OutputPath\n        Path where you want the CAR file (xlsx-file) saved to\n        \n        Default value is: \"c:\\temp\\d365fo.tools\\CAReport.xlsx\"\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the AOS service PackagesLocalDirectory\\bin\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER Module\n        Name of the Module to analyse\n        \n    .PARAMETER Model\n        Name of the Model to analyse\n        \n    .PARAMETER XmlLog\n        Path where you want to store the Xml log output generated from the best practice analyser\n        \n    .PARAMETER PackagesRoot\n        Instructs the cmdlet to use binary metadata\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .PARAMETER SuffixWithModule\n        Instruct the cmdlet to append the module name as a suffix to the desired output file name\n        \n    .EXAMPLE\n        PS C:\\> New-D365CAReport -module \"ApplicationSuite\" -model \"MyOverLayerModel\"\n        \n        This will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module.\n        It will use the default value for the OutputPath parameter, which is \"c:\\temp\\d365fo.tools\\CAReport.xlsx\".\n        \n    .EXAMPLE\n        PS C:\\> New-D365CAReport -OutputPath \"c:\\temp\\CAReport.xlsx\" -module \"ApplicationSuite\" -model \"MyOverLayerModel\"\n        \n        This will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module.\n        It will use the \"c:\\temp\\CAReport.xlsx\" value for the OutputPath parameter.\n        \n    .EXAMPLE\n        PS C:\\> New-D365CAReport -module \"ApplicationSuite\" -model \"MyOverLayerModel\" -SuffixWithModule\n        \n        This will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module.\n        It will use the default value for the OutputPath parameter, which is \"c:\\temp\\d365fo.tools\\CAReport.xlsx\".\n        It will append the module name to the desired output file, which will then be \"c:\\temp\\d365fo.tools\\CAReport-ApplicationSuite.xlsx\".\n        \n    .EXAMPLE\n        PS C:\\> New-D365CAReport -OutputPath \"c:\\temp\\CAReport.xlsx\" -module \"ApplicationSuite\" -model \"MyOverLayerModel\" -PackagesRoot\n        \n        This will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module.\n        It will use the binary metadata to look for the module and model.\n        It will use the \"c:\\temp\\CAReport.xlsx\" value for the OutputPath parameter.\n        \n    .NOTES\n        Author: Tommy Skaue (@Skaue)\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction New-D365CAReport {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]\n    [CmdletBinding()]\n    param (\n        [Alias('File')]\n        [Alias('Path')]\n        [string] $OutputPath = (Join-Path $Script:DefaultTempPath \"CAReport.xlsx\"),\n\n        [Parameter(Mandatory = $true)]\n        [Alias('Package')]\n        [Alias(\"ModuleName\")]\n        [string] $Module,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $Model,\n\n        [switch] $SuffixWithModule,\n\n        [string] $BinDir = \"$Script:PackageDirectory\\bin\",\n\n        [string] $MetaDataDir = \"$Script:MetaDataDir\",\n\n        [string] $XmlLog = (Join-Path $Script:DefaultTempPath \"BPCheckLogcd.xml\"),\n\n        [switch] $PackagesRoot,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\CAReport\"),\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly\n    )\n    \n    if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { return }\n\n    $executable = Join-Path $BinDir \"xppbp.exe\"\n    if (-not (Test-PathExists -Path $executable -Type Leaf)) { return }\n\n    if ($SuffixWithModule) {\n        $OutputPath = $OutputPath.Replace(\".xlsx\", \"-$Module.xlsx\")\n    }\n\n    $params = @(\n        \"-metadata=`\"$MetaDataDir`\"\",\n        \"-all\",\n        \"-module=`\"$Module`\"\",\n        \"-model=`\"$Model`\"\",\n        \"-xmlLog=`\"$XmlLog`\"\",\n        \"-car=`\"$OutputPath`\"\"\n    )\n\n    if ($PackagesRoot -eq $true) {\n        $params += \"-packagesroot=`\"$MetaDataDir`\"\"\n    }\n\n    Write-PSFMessage -Level Verbose -Message \"Starting the $executable with the parameter options.\" -Target $param\n\n    Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    [PSCustomObject]@{\n        File     = $OutputPath\n        Filename = (Split-Path $OutputPath -Leaf)\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/new-d365entraintegration.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Enable the Microsoft Entra ID integration on a cloud hosted environment (CHE).\n        \n    .DESCRIPTION\n        Enable the Microsoft Entra ID integration by executing some of the steps described in https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/dev-tools/secure-developer-vm#external-integrations.\n        The integration can either be enabled with an existing certificate or a new self-signed certificate can be created.\n        If a new certificate is created and the integration is also to be enabled on other environments with the same certificate, a certificate password must be specified in order to create a certificate private key file.\n        \n        The steps executed are:\n        \n        - 1) Create a self-signed certificate and save it to Desktop or use a provided certificate.\n        - 2) Install the certificate to the \"LocalMachine\" certificate store.\n        - 3) Grant NetworkService READ permission to the certificate (only on cloud-hosted environments).\n        - 4) Update the web.config with the application ID and the thumbprint of the certificate.\n        - 5) Add the application registration to the WIF config.\n        - 6) Clear cached LCS configuration in AxDB.\n        - 7) Restart the IIS service.\n        \n        To execute the steps, the id of an Azure application must be provided. The application must have the following API permissions:\n        \n        - Dynamics ERP - This permission is required to access finance and operations environments.\n        - Microsoft Graph (User.Read.All and Group.Read.All permissions of the Application type).\n        - Dynamics Lifecylce service (permission of type Delegated)\n        \n        The URL of the finance and operations environment must also be added to the RedirectURI in the Authentication section of the Azure application.\n        Finally, after running the cmdlet, if a new certificate was created, it must be uploaded to the Azure application.\n        \n    .PARAMETER ClientId\n        The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal.\n        It is assumed that an application with this id already exists in Azure.\n        \n    .PARAMETER ExistingCertificateFile\n        The path to a certificate file. If this parameter is provided, the cmdlet will not create a new certificate.\n        \n    .PARAMETER ExistingCertificatePrivateKeyFile\n        The path to a certificate private key file.\n        If this parameter is not provided, the certificate can be installed to the certificate store, but the NetworkService cannot be granted READ permission.\n        \n    .PARAMETER CertificateName\n        The name for the certificate. By default, it is named \"CHEAuth\".\n        \n    .PARAMETER CertificateExpirationYears\n        The number of years the certificate is valid. By default, it is valid for 2 years.\n        \n    .PARAMETER NewCertificateFile\n        The path to the certificate file that will be created. By default, it is created on the Desktop of the current user.\n        \n    .PARAMETER NewCertificatePrivateKeyFile\n        The path to the certificate private key file that will be created. By default, it is created on the Desktop of the current user.\n        \n    .PARAMETER CertificatePassword\n        The password for the certificate private key file.\n        If not provided when creating a new certificate, no private key file will be created.\n        If not provided when using an existing certificate, the private key file cannot be installed.\n        \n    .PARAMETER Force\n        Forces the execution of some of the steps. For example, if a certificate with the same name already exists, it will be deleted and recreated.\n        \n    .PARAMETER WhatIf\n        Executes the cmdlet until the first operation that would change the state of the system, without executing that operation.\n        Subsequent operations are likely to fail.\n        This is currently not fully implemented and should not be used.\n        \n    .PARAMETER Confirm\n        Prompts for confirmation before each operation of the cmdlet that changes the state of the system.\n        \n    .OUTPUTS\n        If a new certificate is created, the certificate file is placed on the Desktop of the current user.\n        It must be uploaded to the Azure Application.\n        \n    .EXAMPLE\n        PS C:\\> New-D365EntraIntegration -ClientId e70cac82-6a7c-4f9e-a8b9-e707b961e986\n        \n        Enables the Entra ID integration with a new self-signed certificate named \"CHEAuth\" which expires after 2 years.\n        \n    .EXAMPLE\n        PS C:\\> New-D365EntraIntegration -ClientId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -CertificateName \"SelfsignedCert\"\n        \n        Enables the Entra ID integration with a new self-signed certificate with the name \"Selfsignedcert\" that expires after 2 years.\n        \n    .EXAMPLE\n        PS C:\\> New-D365EntraIntegration -AppId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -CertificateName \"SelfsignedCert\" -CertificateExpirationYears 1\n        \n        Enables the Entra ID integration with a new self-signed certificate with the name \"SelfsignedCert\" that expires after 1 year.\n        \n    .EXAMPLE\n        PS C:\\> $securePassword = Read-Host -AsSecureString -Prompt \"Enter the certificate password\"\n        PS C:\\> New-D365EntraIntegration -AppId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -CertificatePassword $securePassword\n        \n        Enables the Entra ID integration with a new self-signed certificate with the name \"CHEAuth\" that expires after 2 years, using the provided password to generate the private key of the certificate.\n        The certificate file and the private key file are saved to the Desktop of the current user.\n        \n    .EXAMPLE\n        PS C:\\> $securePassword = Read-Host -AsSecureString -Prompt \"Enter the certificate password\"\n        PS C:\\> New-D365EntraIntegration -AppId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -ExistingCertificateFile \"C:\\Temp\\SelfsignedCert.cer\" -ExistingCertificatePrivateKeyFile \"C:\\Temp\\SelfsignedCert.pfx\" -CertificatePassword $securePassword\n        \n        Enables the Entra ID integration with the certificate file \"C:\\Temp\\SelfsignedCert.cer\", the private key file \"C:\\Temp\\SelfsignedCert.pfx\" and the provided password to install it.\n        \n    .NOTES\n        Test-D365EntraIntegration can be used to validate an entra integration.\n        \n        Author: Øystein Brenna (@oysbre)\n        Author: Florian Hopfner (@FH-Inway)\n#>\n\nfunction New-D365EntraIntegration {\n    [CmdletBinding(\n        DefaultParameterSetName = \"NewCertificate\",\n        SupportsShouldProcess)]\n    param (\n        \n        [Parameter(Mandatory = $true)]\n        [Alias(\"AppId\")]\n        [string] $ClientId,\n\n        [Parameter(Mandatory = $true, ParameterSetName = \"ExistingCertificate\")]\n        [string] $ExistingCertificateFile,\n    \n        [Parameter(ParameterSetName = \"ExistingCertificate\")]\n        [string] $ExistingCertificatePrivateKeyFile,\n\n        [Parameter(ParameterSetName = \"NewCertificate\")]\n        [string]$CertificateName = \"CHEAuth\",\n\n        [Parameter(ParameterSetName = \"NewCertificate\")]\n        [int]$CertificateExpirationYears = 2,\n\n        [Parameter(ParameterSetName = \"NewCertificate\")]\n        [string] $NewCertificateFile = \"$env:USERPROFILE\\Desktop\\$CertificateName.cer\",\n\n        [Parameter(ParameterSetName = \"NewCertificate\")]\n        [string] $NewCertificatePrivateKeyFile = \"$env:USERPROFILE\\Desktop\\$CertificateName.pfx\",\n\n        [Security.SecureString] $CertificatePassword,\n\n        [switch] $Force\n    )\n\n    if (-not ($Script:IsAdminRuntime)) {\n        Write-PSFMessage -Level Critical -Message \"It seems that you ran this cmdlet <c='em'>non-elevated</c>. Enabling the Entra integration requires you to run this cmdlet from an elevated console. Please exit the current console and start a new with `\"Run As Administrator`\"\"\n        Stop-PSFFunction -Message \"Stopping because the function is not run elevated\"\n        return\n    }\n\n    $certificateStoreLocation = \"Cert:\\LocalMachine\\My\"\n    $certificateThumbprint = \"\"\n\n    # Steps 1 and 2: Create or use existing certificate and install it to the certificate store\n    # Check and install provided certificate file\n    if ($PSCmdlet.ParameterSetName -eq \"ExistingCertificate\") {\n        Write-PSFMessage -Level Verbose -Message \"Steps 1+2: Starting installation of existing certificate\"\n        $params = @{\n            CertificateFile = $ExistingCertificateFile\n            PrivateKeyFile = $ExistingCertificatePrivateKeyFile\n            CertificatePassword = $CertificatePassword\n            Force = $Force\n        }\n        $certificateThumbprint = CheckAndInstallExistingCertificate @params\n    }\n    # Create and install new certificate\n    if ($PSCmdlet.ParameterSetName -eq \"NewCertificate\") {\n        Write-PSFMessage -Level Verbose -Message \"Steps 1+2: Starting creation of new certificate\"\n        $params = @{\n            CertificateName = $CertificateName\n            CertificateExpirationYears = $CertificateExpirationYears\n            NewCertificateFile = $NewCertificateFile\n            NewCertificatePrivateKeyFile = $NewCertificatePrivateKeyFile\n            CertificatePassword = $CertificatePassword\n            Force = $Force\n        }\n        $certificateThumbprint = CreateAndInstallNewCertificate @params\n    }\n\n    # Sanity checks before next steps\n    if (Test-PSFFunctionInterrupt) { return }\n    if (-not $certificateThumbprint) {\n        Write-PSFMessage -Level Host -Message \"Unable to get the certificate thumbprint.\"\n        Stop-PSFFunction -Message \"Stopping because the certificate thumbprint could not be retrieved\"\n        return\n    }\n    $certificateObject = Get-ChildItem $certificateStoreLocation | Where-Object Thumbprint -eq $certificateThumbprint\n    if (-not $certificateObject) {\n        Write-PSFMessage -Level Host -Message \"Unable to get the certificate object.\"\n        Stop-PSFFunction -Message \"Stopping because the certificate object could not be retrieved\"\n        return\n    }\n\n    # Step 3: Grant NetworkService READ permission to the certificate\n    # Check if on cloud-hosted environment\n    if ($Script:EnvironmentType -eq [EnvironmentType]::AzureHostedTier1) {\n        Write-PSFMessage -Level Verbose -Message \"Step 3: Starting granting NetworkService READ permission to the certificate\"\n        Grant-NetworkServiceReadPermissionToCertificate -certificateObject $certificateObject\n        if (Test-PSFFunctionInterrupt) { return }\n    }\n\n    # Step 4: Update web.config with application ID and certificate thumbprint\n    Write-PSFMessage -Level Verbose -Message \"Step 4: Starting updating web.config with application ID and certificate thumbprint\"\n    $params = @{\n        AOSPath = $Script:AOSPath\n        WebConfig = $Script:WebConfig\n        ClientId = $ClientId\n        CertificateThumbprint = $certificateThumbprint\n        Force = $Force\n    }\n    Update-WebConfig @params\n    if (Test-PSFFunctionInterrupt) { return }\n\n    # Step 5: Add app registration to Wif.config\n    Write-PSFMessage -Level Verbose -Message \"Step 5: Starting adding app registration to Wif.config\"\n    Update-WifConfig -AOSPath $Script:AOSPath -WifConfig $Script:WifConfig -ClientId $ClientId -Force:$Force\n    if (Test-PSFFunctionInterrupt) { return }\n\n    # Step 6: Clear cached LCS configuration in AxDB\n    Write-PSFMessage -Level Verbose -Message \"Step 6: Starting clearing cached LCS configuration in AxDB\"\n    Invoke-D365SqlScript -Command \"DELETE FROM SYSOAUTHCONFIGURATION where SECURERESOURCE = 'https://lcsapi.lcs.dynamics.com'\"\n    Invoke-D365SqlScript -Command \"DELETE FROM SYSOAUTHUSERTOKENS where SECURERESOURCE = 'https://lcsapi.lcs.dynamics.com'\"\n    Write-PSFMessage -Level Host -Message \"Cached LCS configuration in AxDB was cleared.\"\n\n    # Step 7: Restart IIS\n    Write-PSFMessage -Level Verbose -Message \"Step 7: Starting restarting IIS\"\n    Restart-D365Environment -Aos\n    Write-PSFMessage -Level Host -Message \"IIS was restarted.\"\n\n    Test-D365EntraIntegration\n\n    if ($PSCmdlet.ParameterSetName -eq \"NewCertificate\") {\n        Write-PSFMessage -Level Host -Message \"The certificate file <c='em'>$NewCertificateFile</c> must be uploaded to the Azure application, see https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app#add-a-certificate.\"\n    }\n}\n\nfunction CheckAndInstallExistingCertificate {\n    [CmdletBinding(SupportsShouldProcess)]\n    param (\n        [Parameter(Mandatory)]\n        [string] $CertificateFile,\n\n        [string] $PrivateKeyFile,\n\n        [Security.SecureString] $CertificatePassword,\n\n        [switch] $Force\n    )\n\n    if (-not (Test-PathExists -Path $CertificateFile -Type Leaf)) {\n        Write-PSFMessage -Level Host -Message \"The provided certificate file <c='em'>$CertificateFile</c> does not exist.\"\n        Stop-PSFFunction -StepsUpward 1 -Message \"Stopping because the provided certificate file does not exist\"\n        return\n    }\n\n    if ($CertificatePassword -and -not (Test-PathExists -Path $PrivateKeyFile -Type Leaf)) {\n        Write-PSFMessage -Level Host -Message \"The provided certificate private key file <c='em'>$PrivateKeyFile</c> does not exist.\"\n        Stop-PSFFunction -StepsUpward 1 -Message \"Stopping because the provided certificate private key file does not exist\"\n        return\n    }\n\n    $certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($CertificateFile)\n    # Check for existing certificate that has the same thumbprint as the provided certificate\n    $existingCertificate = Get-ChildItem -Path $certificateStoreLocation -ErrorAction SilentlyContinue | Where-Object {$_.Thumbprint -eq $certificate.Thumbprint}\n    if ($existingCertificate) {\n        Write-PSFMessage -Level Warning -Message \"A certificate with the same thumbprint as the provided certificate <c='em'>$CertificateFile</c> already exists in <c='em'>$certificateStoreLocation</c>.\"\n        if (-not $Force) {\n            Stop-PSFFunction -StepsUpward 1 -Message \"Stopping because a certificate with the same thumbprint as the provided certificate already exists\"\n            return\n        }\n        Write-PSFMessage -Level Host -Message \"Deleting and installing the provided certificate.\"\n        $existingCertificate | Remove-Item\n    }\n    # Install certificate\n    if ($CertificatePassword) {\n        $null = Import-PfxCertificate -FilePath $PrivateKeyFile -CertStoreLocation $certificateStoreLocation -Password $CertificatePassword\n    }\n    $certificate = Import-Certificate -FilePath $CertificateFile -CertStoreLocation $certificateStoreLocation\n    Write-PSFMessage -Level Host -Message \"Certificate <c='em'>$CertificateFile</c> installed to <c='em'>$certificateStoreLocation</c>.\"\n    $certificate.Thumbprint\n}\n\nfunction CreateAndInstallNewCertificate {\n    [CmdletBinding(SupportsShouldProcess)]\n    param (\n        [Parameter(Mandatory)]\n        [string] $CertificateName,\n\n        [Parameter(Mandatory)]\n        [int] $CertificateExpirationYears,\n\n        [Parameter(Mandatory)]\n        [string] $NewCertificateFile,\n\n        [string] $NewCertificatePrivateKeyFile,\n\n        [Security.SecureString] $CertificatePassword,\n\n        [switch] $Force\n    )\n\n    # Check for existing certificate\n    $existingCertificate = Get-ChildItem -Path $certificateStoreLocation -ErrorAction SilentlyContinue | Where-Object {$_.Subject -Match \"$CertificateName\"}\n    if ($existingCertificate) {\n        Write-PSFMessage -Level Warning -Message \"A certificate with name <c='em'>$CertificateName</c> already exists in <c='em'>$certificateStoreLocation</c> with expiration date <c='em'>$($existingCertificate.NotAfter)</c>.\"\n        if (-not $Force) {\n            Stop-PSFFunction -StepsUpward 1 -Message \"Stopping because a certificate with the same name already exists\"\n            return\n        }\n        Write-PSFMessage -Level Host -Message \"Deleting and re-creating the certificate.\"\n        $existingCertificate | Remove-Item\n    }\n\n    # Check for existing certificate file\n    if (Test-PathExists -Path $NewCertificateFile -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) {\n        Write-PSFMessage -Level Warning -Message \"A certificate file with the same name as the new certificate file <c='em'>$NewCertificateFile</c> already exists.\"\n        if (-not $Force) {\n            Stop-PSFFunction -StepsUpward 1 -Message \"Stopping because a certificate file with the same name already exists\"\n            return\n        }\n        Write-PSFMessage -Level Host -Message \"The existing certificate file will be overwritten.\"\n    }\n    if ($CertificatePassword -and (Test-PathExists -Path $NewCertificatePrivateKeyFile -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue)) {\n        Write-PSFMessage -Level Warning -Message \"A certificate private key file with the same name as the new certificate private key file <c='em'>$NewCertificatePrivateKeyFile</c> already exists.\"\n        if (-not $Force) {\n            Stop-PSFFunction -StepsUpward 1 -Message \"Stopping because a certificate private key file with the same name already exists\"\n            return\n        }\n        Write-PSFMessage -Level Host -Message \"The existing certificate private key file will be overwritten.\"\n    }\n\n    # Create certificate\n    $certificateParams = @{\n        Subject = \"CN=$CertificateName\"\n        CertStoreLocation = $certificateStoreLocation\n        KeyExportPolicy = 'Exportable'\n        KeySpec = 'Signature'\n        KeyLength = 2048\n        KeyAlgorithm = 'RSA'\n        HashAlgorithm = 'SHA256'\n        NotAfter = (Get-Date).AddYears($CertificateExpirationYears)\n    }\n    $certificate = New-SelfSignedCertificate @certificateParams\n    $null = Export-Certificate -Cert $certificate -FilePath $NewCertificateFile -Force:$Force\n    Write-PSFMessage -Level Host -Message \"Certificate <c='em'>$CertificateName</c> created and saved to <c='em'>$NewCertificateFile</c>.\"\n    if ($CertificatePassword) {\n        $null = Export-PfxCertificate -Cert $certificate -FilePath $NewCertificatePrivateKeyFile -Password $CertificatePassword -Force:$Force\n        Write-PSFMessage -Level Host -Message \"Certificate private key file <c='em'>$NewCertificatePrivateKeyFile</c> created.\"\n    }\n    $certificate.Thumbprint\n}\n\nfunction Grant-NetworkServiceReadPermissionToCertificate {\n    [CmdletBinding(SupportsShouldProcess)]\n    param (\n        [Parameter(Mandatory)]\n        [System.Security.Cryptography.X509Certificates.X509Certificate2] $certificateObject\n    )\n\n    # Get private key container name\n    $privateKey = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($certificateObject)\n    $containerName = \"\"\n    if ($privateKey.GetType().Name -ieq \"RSACng\") {\n        $containerName = $privateKey.Key.UniqueName\n    }\n    else {\n        $containerName = $privateKey.CspKeyContainerInfo.UniqueKeyContainerName\n    }\n    $keyFullPath = $env:ProgramData + \"\\Microsoft\\Crypto\\RSA\\MachineKeys\\\" + $containerName\n\n    if (-not (Test-PathExists -Path $keyFullPath -Type Leaf)) {\n        Write-PSFMessage -Level Host -Message \"Unable to get the private key container to set read permission for NetworkService.\"\n        Stop-PSFFunction -StepsUpward 1 -Message \"Stopping because the private key container to set read permission for NetworkService could not be retrieved\"\n        return\n    }\n\n    # Grant NetworkService account access to certificate if it does not already have it\n    $networkServiceSidType = [System.Security.Principal.WellKnownSidType]::NetworkServiceSid\n    $readFileSystemRight = [System.Security.AccessControl.FileSystemRights]::Read\n    $allowAccessControlType = [System.Security.AccessControl.AccessControlType]::Allow\n    $networkServiceSID = New-Object System.Security.Principal.SecurityIdentifier($networkServiceSidType, $null)\n    $permissions = (Get-Item $keyFullPath).GetAccessControl()\n    $newRuleSet = 0\n    $identityNetwork = $permissions.access `\n        | Where-Object {$_.identityreference -eq \"$($networkServiceSID.Translate([System.Security.Principal.NTAccount]).value)\"} `\n        | Select-Object\n\n    if ($identityNetwork.IdentityReference -ne \"$($networkServiceSID.Translate([System.Security.Principal.NTAccount]).value)\") {\n        $rule1 = New-Object Security.AccessControl.FileSystemAccessRule($networkServiceSID, $readFileSystemRight, $allowAccessControlType)\n        $permissions.AddAccessRule($rule1)\n        $newRuleSet = 1\n        Write-PSFMessage -Level Verbose -Message \"Added NetworkService with READ access to certificate\"\n    }\n    elseif ($identityNetwork.FileSystemRights -ne $readFileSystemRight) {\n        $rule1 = New-Object Security.AccessControl.FileSystemAccessRule($networkServiceSID, $readFileSystemRight, $allowAccessControlType)\n        $permissions.AddAccessRule($rule1)\n        $newRuleSet = 1\n        Write-PSFMessage -Level Verbose -Message \"Gave NetworkService READ access to certificate\"\n    }\n\n    if ($newRuleSet -eq 1){\n        Set-Acl -Path $keyFullPath -AclObject $permissions\n        Write-PSFMessage -Level Host -Message \"NetworkService was granted READ permission to the certificate.\"\n    }\n}\n\nfunction Update-WebConfig {\n    [CmdletBinding(SupportsShouldProcess)]\n    param (\n        [Parameter(Mandatory)]\n        [string] $AOSPath,\n\n        [Parameter(Mandatory)]\n        [string] $WebConfig,\n\n        [Parameter(Mandatory)]\n        [string] $ClientId,\n\n        [Parameter(Mandatory)]\n        [string] $CertificateThumbprint,\n\n        [switch] $Force\n    )\n\n    Write-PSFMessage -Level Verbose -Message \"Starting updating web.config\"\n    $webConfigBackup = Join-Path $Script:DefaultTempPath \"WebConfigBackup\"\n    $webConfigFileBackup = Join-Path $webConfigBackup $WebConfig\n    if (Test-PathExists -Path $webConfigFileBackup -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) {\n        Write-PSFMessage -Level Warning -Message \"Backup of web.config already exists.\"\n        if (-not $Force) {\n            Stop-PSFFunction -StepsUpward 1 -Message \"Stopping because a backup of web.config already exists\"\n            return\n        }\n        Write-PSFMessage -Level Host -Message \"Backup of web.config will be overwritten.\"\n    }\n    $null = Backup-D365WebConfig -Force:$Force\n    $webConfigFile = Join-Path -Path $AOSPath $WebConfig\n    if (-not (Test-PathExists -Path $webConfigFile -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue)) {\n        Write-PSFMessage -Level Host -Message \"Unable to find the web.config file.\"\n        Stop-PSFFunction -StepsUpward 1 -Message \"Stopping because the web.config file could not be found\"\n        return\n    }\n    [xml]$xml = Get-Content $webConfigFile\n    $nodes = ($xml.configuration.appSettings).ChildNodes\n    $aadRealm = $nodes | Where-Object -Property Key -eq \"Aad.Realm\"\n    $aadRealm.value = \"spn:$ClientId\"\n    $infraThumb = $nodes | Where-Object -Property Key -eq \"Infrastructure.S2SCertThumbprint\"\n    $infraThumb.value = $CertificateThumbprint\n    $graphThumb = $nodes | Where-Object -Property Key -eq \"GraphApi.GraphAPIServicePrincipalCert\"\n    $graphThumb.value = $CertificateThumbprint\n    if ($PSCmdlet.ShouldProcess($WebConfig, \"Update\")) {\n        $xml.Save($webConfigFile)\n        Write-PSFMessage -Level Host -Message \"web.config was updated with the application ID and the thumbprint of the certificate.\"\n    }\n}\n\nfunction Update-WifConfig {\n    [CmdletBinding(SupportsShouldProcess)]\n    param (\n        [Parameter(Mandatory)]\n        [string] $AOSPath,\n\n        [Parameter(Mandatory)]\n        [string] $WifConfig,\n\n        [Parameter(Mandatory)]\n        [string] $ClientId,\n\n        [switch] $Force\n    )\n\n    Write-PSFMessage -Level Verbose -Message \"Step 5: Starting adding app registration to Wif.config\"\n    $wifConfigBackup = Join-Path $Script:DefaultTempPath \"WifConfigBackup\"\n    $wifConfigFileBackup = Join-Path $wifConfigBackup $WifConfig\n    if (Test-PathExists -Path $wifConfigFileBackup -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) {\n        Write-PSFMessage -Level Warning -Message \"Backup of Wif.config already exists.\"\n        if (-not $Force) {\n            Stop-PSFFunction -StepsUpward 1 -Message \"Stopping because a backup of Wif.config already exists\"\n            return\n        }\n        Write-PSFMessage -Level Host -Message \"Backup of Wif.config will be overwritten.\"\n    }\n    $null = Backup-D365WifConfig -Force:$Force\n    $wifConfigFile = Join-Path -Path $AOSPath $WifConfig\n    if (-not (Test-PathExists -Path $wifConfigFile -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue)) {\n        Write-PSFMessage -Level Host -Message \"Unable to find the Wif.config file.\"\n        Stop-PSFFunction -StepsUpward 1 -Message \"Stopping because the Wif.config file could not be found\"\n        return\n    }\n    [xml]$xml = Get-Content $wifConfigFile\n    $audienceUris = $xml.'system.identityModel'.identityConfiguration.securityTokenHandlers.securityTokenHandlerConfiguration.audienceUris\n    $existingAudienceUri = $audienceUris.ChildNodes | Where-Object {$_.value -eq \"spn:$ClientId\"}\n    if (-not $existingAudienceUri) {\n        $audienceUriElement = $xml.CreateElement('add')\n        $audienceUriElement.SetAttribute('value', \"spn:$ClientId\")\n        $audienceUris.AppendChild($audienceUriElement)\n        if ($PSCmdlet.ShouldProcess($WifConfig, \"Update\")) {\n            $xml.Save($wifConfigFile)\n            Write-PSFMessage -Level Host -Message \"Wif.config was updated with the audience URI.\"\n        }\n    } else {\n        Write-PSFMessage -Level Host -Message \"Audience URI already exists in Wif.config.\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/new-d365isvlicense.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Create a license deployable package\n        \n    .DESCRIPTION\n        Create a deployable package with a license file inside\n        \n    .PARAMETER LicenseFile\n        Path to the license file that you want to have inside a deployable package\n        \n    .PARAMETER Path\n        Path to the template zip file for creating a deployable package with a license file\n        \n        Default path is the same as the aos service \"PackagesLocalDirectory\\bin\\CustomDeployablePackage\\ImportISVLicense.zip\"\n        \n    .PARAMETER OutputPath\n        Path where you want the generated deployable package stored\n        \n        Default value is: \"C:\\temp\\d365fo.tools\\ISVLicense.zip\"\n        \n    .EXAMPLE\n        PS C:\\> New-D365ISVLicense -LicenseFile \"C:\\temp\\ISVLicenseFile.txt\"\n        \n        This will take the \"C:\\temp\\ISVLicenseFile.txt\" file and locate the \"ImportISVLicense.zip\" template file under the \"PackagesLocalDirectory\\bin\\CustomDeployablePackage\\\".\n        It will extract the \"ImportISVLicense.zip\", load the ISVLicenseFile.txt and compress (zip) the files into a deployable package.\n        The package will be exported to \"C:\\temp\\d365fo.tools\\ISVLicense.zip\"\n        \n    .NOTES\n        Author: Mötz Jensen (@splaxi)\n        Author: Szabolcs Eötvös\n        Author: Florian Hopfner (@FH-Inway)\n        \n#>\nfunction New-D365ISVLicense {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n\n        [Parameter(Mandatory = $true, Position = 1)]\n        [string] $LicenseFile,\n\n        [Alias('Template')]\n        [string] $Path = \"$Script:BinDirTools\\CustomDeployablePackage\\ImportISVLicense.zip\",\n\n        [string] $OutputPath = \"C:\\temp\\d365fo.tools\\ISVLicense.zip\"\n\n    )\n\n    begin {\n        $oldprogressPreference = $global:progressPreference\n        $global:progressPreference = 'silentlyContinue'\n    }\n    \n    process {\n        Add-FileToPackage -File $LicenseFile -Archive $Path -Path \"AosService\\Scripts\\License\" -OutputPath $OutputPath -ClearPath\n    }\n\n    end {\n        $global:progressPreference = $oldprogressPreference\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/new-d365moduletoremove.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Create a new ModuleToRemove.txt file\n        \n    .DESCRIPTION\n        Create a new ModuleToRemove.txt file based on a list of module names\n        \n    .PARAMETER Path\n        Path to the ModuleToRemove.txt file\n        \n    .PARAMETER Modules\n        The array with all the module names that you want to fill into the ModuleToRemove.txt file\n        \n    .EXAMPLE\n        PS C:\\> New-D365ModuleToRemove -Path C:\\Temp -Modules \"MyRemovedModule1\",\"MySecondRemovedModule\"\n        \n        This will create a new ModuleToRemove.txt file and fill in \"MyRemovedModule1\" and \"MySecondRemovedModule\" as the modules to remove.\n        The new file is stored at \"C:\\Temp\\ModuleToRemove.txt\"\n        \n    .EXAMPLE\n        PS C:\\> New-D365ModuleToRemove -Path C:\\Temp -Modules \"MyRemovedModule1\",\"MySecondRemovedModule\" | Add-D365ModuleToRemove -DeployablePackage C:\\Temp\\DeployablePackage.zip\n        \n        This will create a new ModuleToRemove.txt file and fill in \"MyRemovedModule1\" and \"MySecondRemovedModule\" as the modules to remove. The file is then added to the \"C:\\Temp\\DeployablePackage.zip\" deployable package.\n        \n    .LINK\n        Add-D365ModuleToRemove\n        \n    .NOTES\n        Author: Florian Hopfner (@FH-Inway)\n        \n#>\nfunction New-D365ModuleToRemove {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 1 )]\n        [alias('Folder')]\n        [string] $Path,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 2 )]\n        [string[]] $Modules\n    )\n\n    begin {\n    }\n\n    process {\n\n        if (Test-PathExists -Path $Path -Type Container) {\n            Remove-Item -Path $Path\\ModuleToRemove.txt -Force -ErrorAction SilentlyContinue\n\n            $Modules | ForEach-Object {\n                Add-Content -Path $Path\\ModuleToRemove.txt -Value $_\n            }\n\n            Write-PSFMessage -Level Host -Message \"ModuleToRemove.txt created at $Path\" -Target $Path\n\n            [PSCustomObject]@{\n                ModuleToRemove = \"$Path\\ModuleToRemove.txt\"\n            }\n\n        }\n        else {\n            Write-PSFMessage -Level Warning -Message \"The path $Path does not exist\" -Target $Path\n        }\n    }\n\n    end {\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/new-d365topologyfile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Create a new topology file\n        \n    .DESCRIPTION\n        Build a new topology file based on a template and update the ServiceModelList\n        \n    .PARAMETER Path\n        Path to the template topology file\n        \n    .PARAMETER Services\n        The array with all the service names that you want to fill into the topology file\n        \n    .PARAMETER NewPath\n        Path to where you want to save the new file after it has been created\n        \n    .EXAMPLE\n        PS C:\\> New-D365TopologyFile -Path C:\\Temp\\DefaultTopologyData.xml -Services \"ALMService\",\"AOSService\",\"BIService\" -NewPath C:\\temp\\CurrentTopology.xml\n        \n        This will read the \"DefaultTopologyData.xml\" file and fill in \"ALMService\",\"AOSService\" and \"BIService\"\n        as the services in the ServiceModelList tag. The new file is stored at \"C:\\temp\\CurrentTopology.xml\"\n        \n    .EXAMPLE\n        PS C:\\> $Services = @(Get-D365InstalledService | ForEach-Object {$_.Servicename})\n        PS C:\\> New-D365TopologyFile -Path C:\\Temp\\DefaultTopologyData.xml -Services $Services -NewPath C:\\temp\\CurrentTopology.xml\n        \n        This will get all the services already installed on the machine. Afterwards the list is piped\n        to New-D365TopologyFile where all services are import into the new topology file that is stored at \"C:\\temp\\CurrentTopology.xml\"\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction New-D365TopologyFile {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 1 )]\n        [alias('File')]\n        [string] $Path,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 2 )]\n        [string[]] $Services,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 3 )]\n        [alias('NewFile')]\n        [string] $NewPath\n    )\n    \n    begin {\n    }\n    \n    process {\n\n        if (Test-PathExists -Path $Path -Type Leaf) {\n            Remove-Item -Path $NewPath -Force -ErrorAction SilentlyContinue\n            \n            [xml]$topology = [xml](Get-Content -Path $Path)\n\n            [System.Collections.ArrayList] $ServicesList = New-Object -TypeName \"System.Collections.ArrayList\"\n            \n            foreach ($obj in $Services) {\n                $null = $ServicesList.Add(\"<string>$obj</string>\")\n            }\n\n            $topology.TopologyData.MachineList.Machine.ServiceModelList.InnerXml = (($ServicesList.ToArray()) -join [Environment]::NewLine )\n            \n            $sw = New-Object System.Io.Stringwriter\n            $writer = New-Object System.Xml.XmlTextWriter($sw)\n            $writer.Formatting = [System.Xml.Formatting]::Indented\n            $writer.Indentation = 4;\n            $topology.WriteContentTo($writer)\n\n            $topology.LoadXml($sw.ToString())\n            $topology.Save(\"$NewPath\")\n        }\n        else {\n            Write-PSFMessage -Level Critical -Message \"The base topology file wasn't found at the specified location. Please check the path and run the cmdlet again.\"\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n    }\n    \n    end {\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/publish-d365ssrsreport.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Deploy Report\n        \n    .DESCRIPTION\n        Deploy SSRS Report to SQL Server Reporting Services\n        \n    .PARAMETER Module\n        Name of the module that you want to works against\n        \n        Accepts an array of strings\n        \n        Default value is \"*\" and will work against all modules loaded on the machine\n        \n    .PARAMETER ReportName\n        Name of the report that you want to deploy\n        \n        Default value is \"*\" and will deploy all reports from the module(s) that you speficied\n        \n    .PARAMETER LogFile\n        Path to the file that should contain the logging information\n        \n        Default value is \"c:\\temp\\d365fo.tools\\AxReportDeployment.log\"\n        \n    .PARAMETER PackageDirectory\n        Path to the PackagesLocalDirectory\n        \n        Default path is the same as the AOS Service PackagesLocalDirectory\n        \n    .PARAMETER ToolsBasePath\n        Base path to the folder containing the needed PowerShell manifests that the cmdlet utilizes\n        \n        Default path is the same as the AOS Service PackagesLocalDirectory\n        \n    .PARAMETER ReportServerIp\n        IP Address of the server that has SQL Reporting Services installed\n        \n        Default value is \"127.0.01\"\n        \n    .EXAMPLE\n        PS C:\\> Publish-D365SsrsReport -Module ApplicationSuite -ReportName TaxVatRegister.Report\n        \n        This will deploy the report which is named \"TaxVatRegister.Report\".\n        The cmdlet will look for the report inside the ApplicationSuite module.\n        The cmdlet will be using the default 127.0.0.1 while deploying the report.\n        \n    .EXAMPLE\n        PS C:\\> Publish-D365SsrsReport -Module ApplicationSuite -ReportName *\n        \n        This will deploy the all reports from the ApplicationSuite module.\n        The cmdlet will be using the default 127.0.0.1 while deploying the report.\n        \n    .NOTES\n        Tags: SSRS, Report, Reports, Deploy, Publish\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Publish-D365SsrsReport {\n    [CmdletBinding()]\n    [OutputType('[PsCustomObject]')]\n    param (\n        [Parameter(Mandatory = $false)]\n        [string[]] $Module = \"*\",\n\n        [Parameter(Mandatory = $false)]\n        [string[]] $ReportName = \"*\",\n\n        [Parameter(Mandatory = $false)]\n        [string] $LogFile = (Join-Path $Script:DefaultTempPath \"AxReportDeployment.log\"),\n\n        [Parameter(Mandatory = $false)]\n        [string] $PackageDirectory = $Script:PackageDirectory,\n\n        [Parameter(Mandatory = $false)]\n        [string] $ToolsBasePath = $Script:PackageDirectory,\n\n        [Parameter(Mandatory = $false)]\n        [string[]]$ReportServerIp = \"127.0.0.1\"\n    )\n\n    Invoke-TimeSignal -Start\n\n    $LogDirectory = Split-Path $LogFile -Parent\n    $toolsPath = Join-Path $ToolsBasePath \"Plugins\\AxReportVmRoleStartupTask\"\n    \n    if (-not (Test-PathExists -Path $toolsPath, $PackageDirectory -Type Container)) { return }\n    if (-not (Test-PathExists -Path $LogDirectory -Type Container -Create)) { return }\n\n    $aosCommonManifest = Join-Path $toolsPath \"AosCommon.psm1\"\n    $reportingManifest = Join-Path $toolsPath \"Reporting.psm1\"\n\n    if (-not (Test-PathExists -Path $aosCommonManifest, $reportingManifest -Type Leaf)) { return }\n\n    Write-PSFMessage -Level Verbose -Message \"Importing the Microsoft AosCommon PowerShell manifest file.\" -Target $aosCommonManifest\n    Import-Module \"$aosCommonManifest\" -Force -DisableNameChecking\n    \n    Write-PSFMessage -Level Verbose -Message \"Importing the Microsoft Reporting PowerShell manifest file.\" -Target $reportingManifest\n    Import-Module \"$reportingManifest\" -Force -DisableNameChecking\n\n    # create JSON config string for Deploy-AxReports\n    $settings = New-Object -TypeName PSCustomObject -Property @{\n        \"BiReporting.ReportingServers\"                       = $($ReportServerIp -join \",\")\n        \"Microsoft.Dynamics.AX.AosConfig.AzureConfig.bindir\" = $PackageDirectory\n        \"Module\"                                             = $Module\n        \"ReportName\"                                         = $ReportName\n    }\n\n    Write-PSFMessage -Level Verbose -Message \"Done building the settings object that will be parsed.\" -Target $settings\n    \n    $jsonConfig = ConvertTo-Json $settings\n\n    Write-PSFMessage -Level Verbose -Message \"Settings object converted to json.\" -Target $jsonConfig\n\n    $jsonConfig = [System.Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($jsonConfig))\n\n    try {\n    \n        Write-PSFMessage -Level Verbose -Message \"Invoking the 'Deploy-AxReport' cmdlet from Microsoft.\"\n\n        Deploy-AxReport -Config $jsonConfig -Log $LogFile\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while deploying the SSRS Report(s)\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n\n    Invoke-TimeSignal -End\n    \n    [PSCustomObject]@{\n\t\tLogFile = $LogFile\n\t}\n}"
  },
  {
    "path": "d365fo.tools/functions/publish-d365webresources.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Deploy web resources\n        \n    .DESCRIPTION\n        Deploys the Dynamics 365 for Finance and Operations web resources to the AOS service web root path.\n        \n    .PARAMETER PackageDirectory\n        Path to the package directory containing the web resources.\n        \n    .PARAMETER AosServiceWebRootPath\n        Path to the AOS service web root path.\n        \n    .EXAMPLE\n        PS C:\\> Publish-D365WebResources\n        \n        This will deploy the web resources to the AOS service web root path.\n        \n    .NOTES\n        Author: Florian Hopfner (@FH-Inway)\n#>\nfunction Publish-D365WebResources {\n    [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', 'Publish-D365WebResources')]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $false)]\n        [PsfDirectory] $PackageDirectory = $Script:PackageDirectory,\n\n        [Parameter(Mandatory = $false)]\n        [PsfDirectory] $AosServiceWebRootPath = $Script:AOSPath\n    )\n  \n    Invoke-TimeSignal -Start\n\n    Write-PSFMessage -Level Verbose -Message \"Initializing web resources deplyoment.\"\n\n    $webResourceTypes = @(\"Images\", \"Scripts\", \"Styles\", \"Html\")\n    \n    Write-PSFMessage -Level Debug -Message \"Creating web resources directory.\"\n    $resourcesDirectory = Join-Path $AosServiceWebRootPath \"Resources\"\n    Test-PathExists -Path $resourcesDirectory -Type Container -Create | Out-Null\n\n    $params = @{\n        ResourceTypes = $webResourceTypes\n        PublishingDirectory = $resourcesDirectory\n        PackageDirectory = $PackageDirectory\n        AosServiceWebRootPath = $AosServiceWebRootPath\n    }\n    Publish-D365FOResources @params\n\n    Write-PSFMessage -Level Host -Message \"Web resources deployment completed.\"\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/register-d365azurestorageconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Register Azure Storage Configurations\n        \n    .DESCRIPTION\n        Register all Azure Storage Configurations\n        \n    .PARAMETER ConfigStorageLocation\n        Parameter used to instruct where to store the configuration objects\n        \n        The default value is \"User\" and this will store all configuration for the active user\n        \n        Valid options are:\n        \"User\"\n        \"System\"\n        \n        \"System\" will store the configuration as default for all users, so they can access the configuration objects\n        \n    .EXAMPLE\n        PS C:\\> Register-D365AzureStorageConfig -ConfigStorageLocation \"System\"\n        \n        This will store all Azure Storage Configurations as defaults for all users on the machine.\n        \n    .NOTES\n        Tags: Configuration, Azure, Storage\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Register-D365AzureStorageConfig {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [ValidateSet('User', 'System')]\n        [string] $ConfigStorageLocation = \"User\"\n    )\n\n    $configScope = Test-ConfigStorageLocation -ConfigStorageLocation $ConfigStorageLocation\n    \n    Register-PSFConfig -FullName \"d365fo.tools.azure.storage.accounts\" -Scope $configScope\n}"
  },
  {
    "path": "d365fo.tools/functions/remove-d365broadcastmessageconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Remove broadcast message configuration\n        \n    .DESCRIPTION\n        Remove a broadcast message configuration from the configuration store\n        \n    .PARAMETER Name\n        Name of the broadcast message configuration you want to remove from the configuration store\n        \n    .PARAMETER Temporary\n        Instruct the cmdlet to only temporarily remove the broadcast message configuration from the configuration store\n        \n    .EXAMPLE\n        PS C:\\> Remove-D365BroadcastMessageConfig -Name \"UAT\"\n        \n        This will remove the broadcast message configuration name \"UAT\" from the machine.\n        \n    .NOTES\n        Tags: Servicing, Broadcast, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n    .LINK\n        Add-D365BroadcastMessageConfig\n        \n    .LINK\n        Clear-D365ActiveBroadcastMessageConfig\n        \n    .LINK\n        Get-D365ActiveBroadcastMessageConfig\n        \n    .LINK\n        Get-D365BroadcastMessageConfig\n        \n    .LINK\n        Send-D365BroadcastMessage\n        \n    .LINK\n        Set-D365ActiveBroadcastMessageConfig\n#>\n\nfunction Remove-D365BroadcastMessageConfig {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [Parameter(Mandatory = $true, Position = 1)]\n        [string] $Name,\n\n        [switch] $Temporary\n    )\n\n    $Name = $Name.ToLower()\n\n    if ($Name -match '\\*') {\n        Write-PSFMessage -Level Host -Message \"The name cannot contain <c='em'>wildcard character</c>.\"\n        Stop-PSFFunction -Message \"Stopping because the name contains wildcard character.\"\n        return\n    }\n\n    if (-not ((Get-PSFConfig -FullName \"d365fo.tools.broadcast.*.name\").Value -contains $Name)) {\n        Write-PSFMessage -Level Host -Message \"A broadcast message configuration with that name <c='em'>doesn't exists</c>.\"\n        Stop-PSFFunction -Message \"Stopping because a broadcast message configuration with that name doesn't exists.\"\n        return\n    }\n\n    $res = (Get-PSFConfig -FullName \"d365fo.tools.active.broadcast.message.config.name\").Value\n\n    if ($res -eq $Name) {\n        Write-PSFMessage -Level Host -Message \"The active broadcast message configuration is the <c='em'>same as the one you're trying to remove</c>. Please set another configuration as active, before removing this one. You could also call Clear-D365ActiveBroadcastMessageConfig.\"\n        Stop-PSFFunction -Message \"Stopping because the active broadcast message configuration is the same as the one trying to be removed.\"\n        return\n    }\n\n    foreach ($config in Get-PSFConfig -FullName \"d365fo.tools.broadcast.$Name.*\") {\n        Set-PSFConfig -FullName $config.FullName -Value \"\"\n\n        if (-not $Temporary) { Unregister-PSFConfig -FullName $config.FullName -Scope UserDefault }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/remove-d365database.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Removes a database\n        \n    .DESCRIPTION\n        Removes a database. By default, if no other database is specified, the AxDB database will be removed.\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .PARAMETER Confirm\n        This parameter will prompt you for confirmation before executing steps of the command that have a medium impact.\n        \n    .PARAMETER WhatIf\n        This parameter will simulate the actions of the command. No changes will be made.\n        \n    .PARAMETER Force\n        This parameter will suppress the confirmation prompt. It can be used as an alternative to -Confirm:$false\n        \n    .EXAMPLE\n        PS C:\\> Remove-D365Database\n        \n        This will remove the \"AxDB\" database from the default SQL Server instance that is registered on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Remove-D365Database -DatabaseName \"ExportClone\"\n        \n        This will remove the \"ExportClone\" from the default SQL Server instance that is registered on the machine.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        Author: Florian Hopfner (@FH-Inway)\n        \n#>\n\nfunction Remove-D365Database {\n    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]\n    param (\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [switch] $EnableException,\n\n        [switch] $Force\n    )\n\n    if ($Force -and -not $PSBoundParameters.ContainsKey('Confirm')) {\n        $ConfirmPreference = 'None'\n    }\n\n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n    \n    $null = [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO')\n\n    $srv = new-object Microsoft.SqlServer.Management.Smo.Server(\"$DatabaseServer\")\n\n    if (-not $UseTrustedConnection) {\n        $srv.ConnectionContext.set_LoginSecure($false)\n        $srv.ConnectionContext.set_Login(\"$SqlUser\")\n        $srv.ConnectionContext.set_Password(\"$SqlPwd\")\n    }\n    \n    try {\n        $db = $srv.Databases[\"$DatabaseName\"]\n\n        if (!$db) {\n            Write-PSFMessage -Level Warning -Message \"Database $DatabaseName not found. Nothing to remove.\"\n            return\n        }\n\n        if ($srv.ServerType -ne \"SqlAzureDatabase\") {\n            if ($PSCmdlet.ShouldProcess(\"$DatabaseName\", \"Kill all processes\")) {\n                $srv.KillAllProcesses(\"$DatabaseName\")\n            }\n        }\n    \n        Write-PSFMessage -Level Verbose -Message \"Dropping $DatabaseName\" -Target $DatabaseName\n    \n        if ($PSCmdlet.ShouldProcess(\"$DatabaseName\", \"Drop database\")) {\n            $db.Drop()\n            Write-PSFMessage -Level Output -Message \"Database $DatabaseName was removed.\"\n        }\n    }\n    catch {\n        $messageString = \"Something went wrong while <c='em'>removing the Database</c>.\"\n        Write-PSFMessage -Level Host -Message $messageString\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -StepsUpward 1\n        return\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/remove-d365lcsassetfile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Delete asset from the LCS project Asset Library\n        \n    .DESCRIPTION\n        Delete asset from the LCS project Asset Library\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER AssetId\n        LCS Id of the file that you are looking for\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        Default value can be configured using Set-D365LcsApiConfig\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Remove-D365LcsAssetFile -ProjectId 123456789 -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\" -AssetId \"812bcb0e-23fb-476d-8a92-985f20a704b9\"\n        \n        This will delete the Asset file from the LCS Asset Library.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .LINK\n        Get-D365LcsApiConfig\n        \n    .LINK\n        Get-D365LcsApiToken\n        \n    .LINK\n        Invoke-D365LcsApiRefreshToken\n        \n    .LINK\n        Set-D365LcsApiConfig\n        \n    .LINK\n        Remove-LcsAssetFile\n        \n    .NOTES\n        Author: Oleksandr Nikolaiev (@onikolaiev)\n        \n#>\nfunction Remove-D365LcsAssetFile {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [int] $ProjectId = $Script:LcsApiProjectId,\n\n        [Parameter(Mandatory = $true)]\n        [string] $AssetId = \"\",\n        \n        [Alias('Token')]\n        [string] $BearerToken = $Script:LcsApiBearerToken,\n\n        [string] $LcsApiUri = $Script:LcsApiLcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    Invoke-TimeSignal -Start\n\n    if (-not ($BearerToken.StartsWith(\"Bearer \"))) {\n        $BearerToken = \"Bearer $BearerToken\"\n    }\n\n    Remove-LcsAssetFile -BearerToken $BearerToken -ProjectId $ProjectId -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout -AssetId $AssetId\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/remove-d365model.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Remove a model from Dynamics 365 for Finance & Operations\n        \n    .DESCRIPTION\n        Remove a model from a Dynamics 365 for Finance & Operations environment\n        \n    .PARAMETER Model\n        Name of the model that you want to work against\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the AOS service PackagesLocalDirectory\\bin\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER DeleteFolders\n        Instruct the cmdlet to delete the model folder\n        \n        This is useful when you are trying to clean up the folders in your source control / branch\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .EXAMPLE\n        PS C:\\> Remove-D365Model -Model CustomModelName\n        \n        This will remove the \"CustomModelName\" model from the D365FO environment.\n        It will NOT remove the folders inside the PackagesLocalDirectory location.\n        \n    .EXAMPLE\n        PS C:\\> Remove-D365Model -Model CustomModelName -DeleteFolders\n        \n        This will remove the \"CustomModelName\" model from the D365FO environment.\n        It will remove the folders inside the PackagesLocalDirectory location.\n        This is helpful when dealing with source control and you want to remove the model entirely.\n        \n    .NOTES\n        Tags: ModelUtil, Axmodel, Model, Remove, Delete, Source Control, Vsts, Azure DevOps\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Remove-D365Model {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    \n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $Model,\n\n        [Parameter(Mandatory = $false)]\n        [string] $BinDir = \"$Script:PackageDirectory\\bin\",\n\n        [Parameter(Mandatory = $false)]\n        [string] $MetaDataDir = \"$Script:MetaDataDir\",\n\n        [switch] $DeleteFolders,\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly\n    )\n\n    Invoke-TimeSignal -Start\n    \n    Invoke-ModelUtil -Command \"Delete\" -Path $Path -BinDir $BinDir -MetaDataDir $MetaDataDir -Model $Model -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    $modelPath = Join-Path $MetaDataDir $Model\n\n    if ($DeleteFolders) {\n        if (-not (Test-PathExists -Path $modelPath -Type Container)) { return }\n\n        Remove-Item $modelPath -Force  -Recurse -ErrorAction SilentlyContinue\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/functions/remove-d365user.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Delete an user from the environment\n        \n    .DESCRIPTION\n        Deletes the user from the database, including security configuration\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER Email\n        The search string to select which user(s) should be updated.\n        \n        You have to specific the explicit email address of the user you want to remove\n        \n        The cmdlet will not be able to delete the ADMIN user, this is to prevent you\n        from being locked out of the system.\n        \n    .EXAMPLE\n        PS C:\\> Remove-D365User -Email \"Claire@contoso.com\"\n        \n        This will move all security and user details from the user with the email address\n        \"Claire@contoso.com\"\n        \n    .EXAMPLE\n        PS C:\\> Get-D365User -Email *contoso.com | Remove-D365User\n        \n        This will first get all users from the database that matches the *contoso.com\n        search and pipe their emails to Remove-D365User for it to delete them.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Remove-D365User {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $false, Position = 1)]\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Mandatory = $false, Position = 2)]\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false, Position = 3)]\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false, Position = 4)]\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 5)]\n        [string] $Email\n\n    )\n\n    BEGIN {\n        $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n        $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n            SqlUser = $SqlUser; SqlPwd = $SqlPwd\n        }\n\n        $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n\n        try {\n            $SqlCommand.Connection.Open()\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n    }\n    \n    PROCESS {\n        if(Test-PSFFunctionInterrupt) {return}\n\n        $SqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\remove-user.sql\") -join [Environment]::NewLine\n    \n        $null = $SqlCommand.Parameters.AddWithValue(\"@Email\", $Email)\n    \n        try {\n            Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n            $null = $SqlCommand.ExecuteNonQuery()\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n\n        $SqlCommand.Parameters.Clear()\n    }\n    \n    END {\n        try {\n            if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n                $sqlCommand.Connection.Close()\n            }\n            $sqlCommand.Dispose()\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/rename-d365computername.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Function for renaming computer.\n        Renames Computer and changes the SSRS Configration\n        \n    .DESCRIPTION\n        When doing development on-prem, there is as need for changing the Computername.\n        Function both changes Computername and SSRS Configuration\n        \n    .PARAMETER NewName\n        The new name for the computer\n        \n    .PARAMETER SSRSReportDatabase\n        Name of the SSRS reporting database\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n        When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Rename-D365ComputerName -NewName \"Demo-8.1\" -SSRSReportDatabase \"ReportServer\"\n        \n        This will rename the local machine to the \"Demo-8.1\" as the new Windows machine name.\n        It will update the registration inside the SQL Server Reporting Services configuration to handle the new name of the machine.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Rename-D365ComputerName {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $NewName,\n\n        [string] $SSRSReportDatabase = \"DynamicsAxReportServer\",\n\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n\n        [Alias('LogDir')]\n        [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\RsConfig\"),\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly,\n\n        [switch] $EnableException\n    )\n\n    Write-PSFMessage -Level Verbose -Message \"Testing for elevated runtime\"\n    \n    if (!$script:IsAdminRuntime) {\n        Write-PSFMessage -Level Host -Message \"The cmdlet needs <c='em'>administrator permission</c> (Run As Administrator) to be able to update the configuration. Please start an <c='em'>elevated</c> session and run the cmdlet again.\"\n        Stop-PSFFunction -Message \"Stopping because the function is not run elevated\"\n        return\n    }\n\n    $executable = \"$Script:SSRSTools\\rsconfig.exe\"\n    $SSRSInstance = \"SSRS\"\n\n    if (-not (Test-PathExists -Path $executable -Type Leaf)) {\n        $executable = \"$Script:SQLTools\\rsconfig.exe\" # fall back to pre 10.0.24\n        $SSRSInstance = \"\"  # no instance name needed for old VMs\n\n        if (-not (Test-PathExists -Path $executable -Type Leaf)) { return }\n    }\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    Write-PSFMessage -Level Verbose -Message \"Renaming computer to $NewName\"\n\n    Rename-Computer -NewName $NewName -Force\n\n    Write-PSFMessage -Level Verbose -Message \"Renaming local server name inside SQL Server to $NewName\"\n\n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n    \n    $Params = @{DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd; TrustedConnection = $UseTrustedConnection;\n    }\n\n    $oldComputerName = $env:COMPUTERNAME\n\n    $sqlCommand = Get-SQLCommand @Params\n\n    $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\rename-computer.sql\") -join [Environment]::NewLine\n    $commandText = $commandText.Replace('@OldComputerName', $oldComputerName)\n    $commandText = $commandText.Replace('@NewComputerName', $NewName)\n\n    $sqlCommand.CommandText = $commandText\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n\n        $null = $sqlCommand.ExecuteNonQuery()\n    }\n    catch {\n        $messageString = \"Something went wrong while working against the database.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand)\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n    }\n\n    $sqlCommand = Get-SQLCommand @Params\n\n    Write-PSFMessage -Level Verbose -Message \"Setting SSRS Reporting server database server to localhost\"\n\n    $params = New-Object System.Collections.Generic.List[string]\n    $params.Add(\"-s\")\n    $params.Add(\"localhost\")\n    $params.Add(\"-a\")\n    $params.Add(\"Windows\")\n    $params.Add(\"-c\")\n    $params.Add(\"-d\")\n    $params.Add(\"`\"$SSRSReportDatabase`\"\")\n\n    if ($SSRSInstance) {\n        $params.Add(\"-i\")\n        $params.Add(\"`\"$SSRSInstance`\"\")\n    }\n\n    Invoke-Process -Executable $executable -Params $params.ToArray() -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n\n    if (-not $OutputCommandOnly) {\n        Write-PSFMessage -Level Host -Message \"Computer has been <c='em'>renamed</c>. Please <c='em'>restart the computer</c> to make sure that all changes are being applied correctly.\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/rename-d365instance.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Rename as D365FO Demo/Dev box\n        \n    .DESCRIPTION\n        The Rename function, changes the config values used by a D365FO dev box for identifying its name. Standard it is called 'usnconeboxax1aos'\n        \n    .PARAMETER NewName\n        The new name wanted for the D365FO instance\n        \n    .PARAMETER AosServiceWebRootPath\n        Path to the webroot folder for the AOS service 'Default value : C:\\AOSService\\Webroot\n        \n    .PARAMETER IISServerApplicationHostConfigFile\n        Path to the IISService Application host file, [Where the binding configurations is stored] 'Default value : C:\\Windows\\System32\\inetsrv\\Config\\applicationHost.config'\n        \n    .PARAMETER HostsFile\n        Place of the host file on the current system [Local DNS record] ' Default value C:\\Windows\\System32\\drivers\\etc\\hosts'\n        \n    .PARAMETER BackupExtension\n        Backup name for all the files that are changed\n        \n    .PARAMETER MRConfigFile\n        Path to the Financial Reporter (Management Reporter) configuration file\n        \n    .EXAMPLE\n        PS C:\\> Rename-D365Instance -NewName \"Demo1\"\n        \n        This will rename the D365 for Finance & Operations instance to \"Demo1\".\n        This IIS will be restarted while doing it.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n        The function restarts the IIS Service.\n        Elevated privileges are required.\n        \n#>\nfunction Rename-D365Instance {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string]$NewName,\n\n        [string]$AosServiceWebRootPath = $Script:AOSPath,\n\n        [string]$IISServerApplicationHostConfigFile = $Script:IISHostFile,\n\n        [string]$HostsFile = $Script:Hosts,\n\n        [string]$BackupExtension = \"bak\",\n\n        [string]$MRConfigFile = $Script:MRConfigFile\n\n    )\n\n    Write-PSFMessage -Level Verbose -Message \"Testing for elevated runtime\"\n\n    if ($Script:EnvironmentType -ne [EnvironmentType]::LocalHostedTier1) {\n        Write-PSFMessage -Level Host -Message \"It seems that you ran this cmdlet on a machine that is not a local hosted tier 1 / one box. This cmdlet is only supporting on a <c='em'>onebox / local tier 1</c> machine.\"\n        Stop-PSFFunction -Message \"Stopping because machine isn't a onebox\"\n        return\n    }\n    elseif (!$script:IsAdminRuntime) {\n        Write-PSFMessage -Level Host -Message \"The cmdlet needs <c='em'>administrator permission</c> (Run As Administrator) to be able to update the configuration. Please start an <c='em'>elevated</c> session and run the cmdlet again.\"\n        Stop-PSFFunction -Message \"Stopping because the function is not run elevated\"\n        return\n    }\n\n    $OldName = (Get-D365InstanceName).Instancename\n\n    Write-PSFMessage -Level Verbose -Message \"Old name collected and will be used to rename.\" -Target $OldName\n\n    # Variables\n    $replaceValue = $OldName\n    $NewNameDot = \"$NewName.\"\n    $replaceValueDot = \"$replaceValue.\"\n\n    $WebConfigFile = join-Path -path $AosServiceWebRootPath $Script:WebConfig\n    $WifServicesFile = Join-Path -Path $AosServiceWebRootPath $Script:WifServicesConfig\n\n    $Files = @($WebConfigFile, $WifServicesFile, $IISServerApplicationHostConfigFile, $HostsFile, $MRConfigFile)\n    if(-not (Test-PathExists -Path $Files -Type Leaf)) {\n        return\n    }\n\n    Write-PSFMessage -Level Verbose -Message \"Stopping the IIS.\"\n    iisreset /stop\n\n    # Backup files\n    if ($null -ne $BackupExtension -and $BackupExtension -ne '') {\n        foreach ($item in $Files) {\n            Backup-File -File $item -Suffix $BackupExtension\n        }\n    }\n\n    # WebConfig - D365 web config file\n    Rename-ConfigValue $WebConfigFile $NewName $replaceValue\n    # Wif.Services - D365 web config file (services)\n    Rename-ConfigValue $WifServicesFile $NewName $replaceValue\n    #ApplicationHost - IIS Bindings\n    Rename-ConfigValue $IISServerApplicationHostConfigFile $NewNameDot $replaceValueDot\n    #Hosts file - local DNS cache\n    Rename-ConfigValue $HostsFile $NewNameDot $replaceValueDot\n    #Management Reporter\n    Rename-ConfigValue $MRConfigFile $NewName $replaceValue\n\n    #Start IIS again\n    Write-PSFMessage -Level Verbose -Message \"Starting the IIS.\"\n    iisreset /start\n\n    Get-D365Url -Force\n}"
  },
  {
    "path": "d365fo.tools/functions/repair-d365bacpacmodelfile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Repair a bacpac model file\n        \n    .DESCRIPTION\n        As the backend of the Azure SQL infrastructure keeps evolving, the bacpac file can contain invalid instructions while we are trying to import into a local SQL Server installation on a Tier1 environment\n        \n    .PARAMETER Path\n        Path to the bacpac model file that you want to work against\n        \n    .PARAMETER OutputPath\n        Path to where the repaired model file should be placed\n        \n        The default value is going to create a file next to the Path (input) file, with the '-edited' name appended to it\n        \n    .PARAMETER PathRepairSimple\n        Path to the json file, that contains all the instructions to be executed in the \"Simple\" section\n        \n        The default json file is part of the module, and can be located with the below command:\n        explorer.exe $(Join-Path -Path $(Split-Path -Path (Get-Module d365fo.tools -ListAvailable)[0].Path -Parent) -ChildPath \"internal\\misc\")\n        - Look for the \"RepairBacpac.Simple.json\" file\n        \n        Or you can see the latest version, online, inside the github repository: https://github.com/d365collaborative/d365fo.tools/tree/master/d365fo.tools/internal/misc/RepairBacpac.Simple.json\n        \n        Simple means, that we can remove complex elements, based on some basic logic. E.g.\n        \n        {\n        \"Search\": \"*<Element Type=\\\"SqlPermissionStatement\\\"*ms_db_configreader*\",\n        \"End\": \"*</Element>*\"\n        }\n        \n        \"*<Element Type=\\\"SqlPermissionStatement\\\"*ms_db_configreader*\" can identify below, and together with \"*</Element>*\" - we know when to stop.\n        \n        <Element Type=\"SqlPermissionStatement\" Name=\"[Grant.Delete.Object].[ms_db_configreader].[dbo].[dbo].[AutotuneBase]\">\n        <Property Name=\"Permission\" Value=\"4\" />\n        <Relationship Name=\"Grantee\">\n        <Entry>\n        <References Name=\"[ms_db_configreader]\" />\n        </Entry>\n        </Relationship>\n        <Relationship Name=\"Grantor\">\n        <Entry>\n        <References ExternalSource=\"BuiltIns\" Name=\"[dbo]\" />\n        </Entry>\n        </Relationship>\n        <Relationship Name=\"SecuredObject\">\n        <Entry>\n        <References Name=\"[dbo].[AutotuneBase]\" />\n        </Entry>\n        </Relationship>\n        </Element>\n        \n    .PARAMETER PathRepairQualifier\n        Path to the json file, that contains all the instructions to be executed in the \"Qualifier\" section\n        \n        The default json file is part of the module, and can be located with the below command:\n        explorer.exe $(Join-Path -Path $(Split-Path -Path (Get-Module d365fo.tools -ListAvailable)[0].Path -Parent) -ChildPath \"internal\\misc\")\n        - Look for the \"RepairBacpac.Qualifier.json\" file\n        \n        Or you can see the latest version, online, inside the github repository: https://github.com/d365collaborative/d365fo.tools/tree/master/d365fo.tools/internal/misc/RepairBacpac.Qualifier.json\n        \n        Qualifier means, that we can remove complex elements, based on some basic logic. E.g.\n        \n        {\n        \"Search\": \"*<Element Type=\\\"SqlRoleMembership\\\">*\",\n        \"Qualifier\": \"*<References Name=*ms_db_configwriter*\",\n        \"End\": \"*</Element>*\"\n        }\n        \n        \"*<Element Type=\\\"SqlRoleMembership\\\">*\" can identify below, \"*<References Name=*ms_db_configwriter*\" qualifies that we are locating the correct one and together with \"*</Element>*\" - we know when to stop.\n        \n        <Element Type=\"SqlRoleMembership\">\n        <Relationship Name=\"Member\">\n        <Entry>\n        <References Name=\"[ms_db_configwriter]\" />\n        </Entry>\n        </Relationship>\n        <Relationship Name=\"Role\">\n        <Entry>\n        <References ExternalSource=\"BuiltIns\" Name=\"[db_ddladmin]\" />\n        </Entry>\n        </Relationship>\n        </Element>\n        \n    .PARAMETER PathRepairReplace\n        Path to the json file, that contains all the instructions to be executed in the \"Replace\" section\n        \n        The default json file is part of the module, and can be located with the below command:\n        explorer.exe $(Join-Path -Path $(Split-Path -Path (Get-Module d365fo.tools -ListAvailable)[0].Path -Parent) -ChildPath \"internal\\misc\")\n        - Look for the \"RepairBacpac.Replace.json\" file\n        \n        Or you can see the latest version, online, inside the github repository: https://github.com/d365collaborative/d365fo.tools/tree/master/d365fo.tools/internal/misc/RepairBacpac.Replace.json\n        \n        Replace means, that we can replace/remove strings, based on some basic logic. E.g.\n        \n        {\n        \"Search\": \"<Property Name=\\\"AutoDrop\\\" Value=\\\"True\\\" />\",\n        \"Replace\": \"\"\n        }\n        \n        \"<Property Name=\\\"AutoDrop\\\" Value=\\\"True\\\" />\" can identify below, and \"\" is the value we want to replace with it.\n        \n        <Property Name=\"AutoDrop\" Value=\"True\" />\n        \n    .PARAMETER KeepFiles\n        Instruct the cmdlet to keep the files from the repair process\n        \n        The files are very large, so only use this as a way to analyze why your model file didn't end up in the desired state\n        \n        Use it while you evolve/develop your instructions, but remove it from ANY full automation scripts\n        \n    .PARAMETER Force\n        Instruct the cmdlet to overwrite the file specified in the OutputPath if it already exists\n        \n    .EXAMPLE\n        PS C:\\> Repair-D365BacpacModelFile -Path C:\\Temp\\Base.xml -PathRepairSimple '' -PathRepairQualifier '' -PathRepairReplace 'C:\\Temp\\RepairBacpac.Replace.Custom.json'\n        \n        This will only process the Replace section, as the other repair paths are empty - indicating to skip them.\n        It will load the instructions from the 'C:\\Temp\\RepairBacpac.Replace.Custom.json' file and run those in the Replace section.\n        \n    .EXAMPLE\n        PS C:\\> Repair-D365BacpacModelFile -Path C:\\Temp\\Base.xml -KeepFiles -Force\n        \n        This will process all repair sections.\n        It will keep the files in the temporary work directory, for the user to analyze the files further.\n        It will Force overwrite the output file, if it exists already.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        Author: Florian Hopfner (@FH-Inway)\n        \n        Json files has to be an array directly in the root of the file. All \" (double quotes) has to be escaped with \\\" - otherwise it will not work as intended.\n        \n        This cmdlet is inspired by the work of \"Brad Bateman\" (github: @batetech)\n        \n        His github profile can be found here:\n        https://github.com/batetech\n        \n        Florian Hopfner did a gist implementation, which has been used as the foundation for this implementation\n        \n        The original gist is: https://gist.github.com/FH-Inway/f485c720b43b72bffaca5fb6c094707e\n        \n        His github profile can be found here:\n        https://github.com/FH-Inway\n#>\nfunction Repair-D365BacpacModelFile {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory)]\n        [string] $Path,\n\n        [string] $OutputPath,\n\n        [string] $PathRepairSimple = \"$script:ModuleRoot\\internal\\misc\\RepairBacpac.Simple.json\",\n\n        [string] $PathRepairQualifier = \"$script:ModuleRoot\\internal\\misc\\RepairBacpac.Qualifier.json\",\n\n        [string] $PathRepairReplace = \"$script:ModuleRoot\\internal\\misc\\RepairBacpac.Replace.json\",\n\n        [switch] $KeepFiles,\n\n        [switch] $Force\n\n    )\n    begin {\n        Invoke-TimeSignal -Start\n\n        if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        if ([string]::IsNullOrEmpty($OutputPath)) {\n            $OutputPath = $Path.Replace([System.IO.Path]::GetExtension($path), \"-edited$([System.IO.Path]::GetExtension($path))\")\n        }\n\n        if (-not $Force) {\n            if (-not (Test-PathExists -Path $OutputPath -Type Leaf -ShouldNotExist)) {\n                Write-PSFMessage -Level Host -Message \"The <c='em'>$OutputPath</c> already exists. Consider changing the <c='em'>OutputPath</c> or set the <c='em'>Force</c> parameter to overwrite the file.\"\n                Stop-PSFFunction -Message \"Stopping because output path was already present.\"\n                return\n            }\n        }\n\n        if (Test-PSFFunctionInterrupt) { return }\n    }\n    \n    end {\n        if (Test-PSFFunctionInterrupt) { return }\n\n        # Create a local working directory, in the temporary directory\n        $directoryObj = New-Item -Path \"$([System.IO.Path]::GetTempPath())$((New-Guid).Guid)\" -ItemType Directory -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\n    \n        if ($KeepFiles) {\n            Write-PSFMessage -Level Host -Message \"The working directory used for this repair is:`r`n<c='em'>$($directoryObj.FullName)</c>`r`n - Please only use the KeepFiles when needed.\"\n        }\n\n        # Path to help us keep track of the file and what changes have been made - troubleshooting is easier with this one\n        $localInput = Join-Path -Path $directoryObj.FullName -ChildPath \"raw.simple&replace.input.xml\"\n        $forOutput = Join-Path -Path $directoryObj.FullName -ChildPath \"0.simple&replace.output.xml\"\n\n        # Clone input file to the local temporary file\n        Copy-Item -Path $Path -Destination $localInput -Force\n\n        $arrSimple = @()\n        if (-not [string]::IsNullOrEmpty($PathRepairSimple)) {\n            # Load all the simple delete instructions\n            $arrSimple = Get-Content -Path $PathRepairSimple -Raw | ConvertFrom-Json\n        }\n\n        $arrReplace = @()\n        if (-not [string]::IsNullOrEmpty($PathRepairReplace)) {\n            # Load all the replace instructions\n            $arrReplace = Get-Content -Path $PathRepairReplace -Raw | ConvertFrom-Json\n        }\n\n        Write-PSFMessage -Level Verbose -Message \"Starting the Remove and Replace section of the repair.\" -Target @($arrSimple, $arrReplace)\n\n        Repair-BacpacModelSimpleAndReplace -Path $localInput -OutputPath $forOutput -RemoveInstructions $arrSimple -ReplaceInstructions $arrReplace\n\n        $arrQualifier = @()\n        if (-not [string]::IsNullOrEmpty($PathRepairQualifier)) {\n            # Load all the qualification delete instructions\n            $arrQualifier = Get-Content -Path $PathRepairQualifier -Raw | ConvertFrom-Json\n        }\n\n        # Path to help us keep track of the file and what changes have been made - troubleshooting is easier with this one\n        $localInput = Join-Path -Path $directoryObj.FullName -ChildPath \"raw.qualifier.input.xml\"\n\n        # Clone input file to the local temporary file\n        Copy-Item -Path $forOutput -Destination $localInput -Force\n\n        if (-not $KeepFiles) {\n            Get-ChildItem -Path \"$($directoryObj.FullName)\\*.simple&replace.*.xml\" | Remove-Item -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\n        }\n\n        Write-PSFMessage -Level Verbose -Message \"Starting the Qualifier section of the repair.\" -Target @($arrSimple, $arrReplace)\n\n        for ($i = 0; $i -lt $arrQualifier.Count; $i++) {\n            $forInput = Join-Path -Path $directoryObj.FullName -ChildPath \"$i.qualifier.input.xml\"\n            $forOutput = Join-Path -Path $directoryObj.FullName -ChildPath \"$i.qualifier.output.xml\"\n\n            Copy-Item -Path $localInput -Destination $forInput -Force\n            Repair-BacpacModelQualifier -Path $forInput -OutputPath $forOutput -Search $arrQualifier[$i].Search -Qualifier $arrQualifier[$i].Qualifier -End $arrQualifier[$i].End\n\n            $localInput = $forOutput\n        }\n\n        if ($arrQualifier.Count -lt 1) {\n            $forOutput = $localInput\n        }\n\n        Copy-Item -Path $forOutput -Destination $OutputPath -Force\n\n        if (-not $KeepFiles) {\n            Get-ChildItem -Path \"$($directoryObj.FullName)\\*.qualifier.*.xml\" | Remove-Item -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\n        }\n\n        [PSCustomObject]@{\n            File     = $OutputPath\n            Filename = $(Split-Path -Path $OutputPath -Leaf)\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/restart-d365environment.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Restart the different services\n        \n    .DESCRIPTION\n        Restart the different services in a Dynamics 365 Finance & Operations environment\n        \n    .PARAMETER ComputerName\n        An array of computers that you want to work against\n        \n    .PARAMETER All\n        Instructs the cmdlet work against all relevant services\n        \n        Includes:\n        Aos\n        Batch\n        Financial Reporter\n        DMF\n        \n    .PARAMETER Aos\n        Instructs the cmdlet to work against the AOS (IIS) service\n        \n    .PARAMETER Batch\n        Instructs the cmdlet to work against the Batch service\n        \n    .PARAMETER FinancialReporter\n        Instructs the cmdlet to work against the Financial Reporter (Management Reporter 2012)\n        \n    .PARAMETER DMF\n        Instructs the cmdlet to work against the DMF service\n        \n    .PARAMETER Kill\n        Instructs the cmdlet to kill the service(s) that you want to restart\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .EXAMPLE\n        PS C:\\> Restart-D365Environment -All\n        \n        This will stop all services and then start all services again.\n        \n    .EXAMPLE\n        PS C:\\> Restart-D365Environment -All -ShowOriginalProgress\n        \n        This will stop all services and then start all services again.\n        The progress of Stopping the different services will be written to the console / host.\n        The progress of Starting the different services will be written to the console / host.\n        \n    .EXAMPLE\n        PS C:\\> Restart-D365Environment -ComputerName \"TEST-SB-AOS1\",\"TEST-SB-AOS2\",\"TEST-SB-BI1\" -All\n        \n        This will work against the machines: \"TEST-SB-AOS1\",\"TEST-SB-AOS2\",\"TEST-SB-BI1\".\n        This will stop all services and then start all services again.\n        \n    .EXAMPLE\n        PS C:\\> Restart-D365Environment -Aos -Batch\n        \n        This will stop the AOS and Batch services and then start the AOS and Batch services again.\n        \n    .EXAMPLE\n        PS C:\\> Restart-D365Environment -FinancialReporter -DMF\n        \n        This will stop the FinancialReporter and DMF services and then start the FinancialReporter and DMF services again.\n        \n    .EXAMPLE\n        PS C:\\> Restart-D365Environment -All -Kill\n        \n        This will stop all services and then start all services again.\n        It will use the Kill parameter to make sure that the services is stopped.\n        \n    .NOTES\n        Tags: Environment, Service, Services, Aos, Batch, Servicing\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Restart-D365Environment {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidDefaultValueSwitchParameter\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    \n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 1 )]\n        [string[]] $ComputerName = @($env:computername),\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )]\n        [switch] $All = $true,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 2 )]\n        [switch] $Aos,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 3 )]\n        [switch] $Batch,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 4 )]\n        [switch] $FinancialReporter,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 5 )]\n        [switch] $DMF,\n\n        [switch] $Kill,\n\n        [Parameter(Mandatory = $False)]\n        [switch] $ShowOriginalProgress\n    )\n\n    Stop-D365Environment @PSBoundParameters | Format-Table\n    \n    $parms = Get-DeepClone $PSBoundParameters\n    if ($parms.ContainsKey(\"Kill\")) { $null = $Params.Remove(\"Kill\") }\n\n    Start-D365Environment @parms | Format-Table\n}"
  },
  {
    "path": "d365fo.tools/functions/restore-d365devconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Restore the DynamicsDevConfig.xml file\n        \n    .DESCRIPTION\n        Will restore the DynamicsDevConfig.xml file located in the PackagesLocalDirectory\\Bin folder\n        \n    .PARAMETER Path\n        Path to the folder where you the desired DynamicsDevConfig.xml file that you want restored is located\n        \n        Default is: \"C:\\Temp\\d365fo.tools\\DevConfigBackup\"\n        \n    .PARAMETER Force\n        Instructs the cmdlet to overwrite the destination file if it already exists\n        \n    .EXAMPLE\n        PS C:\\> Restore-D365DevConfig -Force\n        \n        Will restore the DynamicsDevConfig.xml file, and overwrite the current DynamicsDevConfig.xml file in the PackagesLocalDirectory\\Bin folder.\n        It will use the default path \"C:\\Temp\\d365fo.tools\\DevConfigBackup\" as the source directory.\n        It will overwrite the current DynamicsDevConfig.xml file.\n        \n        A result set example:\n        \n        Filename              LastModified         File\n        --------              ------------         ----\n        DynamicsDevConfig.xml 6/29/2021 7:31:04 PM K:\\AosService\\PackagesLocalDirectory\\Bin\\DynamicsDevConfig.xml\n        \n    .NOTES\n        Tags: Web Server, IIS, IIS Express, Development\n        \n        Author: Sander Holvoet (@smholvoet)\n        \n#>\nfunction Restore-D365DevConfig {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [string] $Path = $(Join-Path $Script:DefaultTempPath \"DevConfigBackup\"),\n\n        [switch] $Force\n    )\n\n    begin {\n        if ($Path -like \"*$($Script:DevConfig)\") {\n            $sourceFile = $Path\n        }\n        else {\n            $sourceFile = $(Join-Path -Path $Path -ChildPath $Script:DevConfig)\n        }\n    }\n    \n    process {\n\n        if (-not (Test-PathExists -Path $sourceFile -Type Leaf)) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n    \n        $destinationFile = $(Join-Path -Path (Join-Path -Path $Script:PackageDirectory -ChildPath \"bin\") -ChildPath $Script:DevConfig)\n\n        if (-not $Force) {\n            if ((-not (Test-PathExists -Path $destinationFile -Type Leaf -ShouldNotExist -ErrorAction SilentlyContinue -WarningAction SilentlyContinue))) {\n                Write-PSFMessage -Level Host -Message \"The <c='em'>$destinationFile</c> already exists. Consider changing the <c='em'>destination</c> path or set the <c='em'>Force</c> parameter to overwrite the file.\"\n                return\n            }\n        }\n\n        Write-PSFMessage -Level Verbose -Message \"Copying from: $sourceFile\" -Target $item\n        Copy-Item -Path $sourceFile -Destination $destinationFile -Force:$Force -PassThru | Select-PSFObject \"Name as Filename\", \"LastWriteTime as LastModified\", \"Fullname as File\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/restore-d365webconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Restore the web.config file\n        \n    .DESCRIPTION\n        Will restore the web.config file located back into the AOS / IIS folder\n        \n    .PARAMETER Path\n        Path to the folder where you the desired web.config file that you want restored is located\n        \n        Default is: \"C:\\Temp\\d365fo.tools\\WebConfigBackup\"\n        \n    .PARAMETER Force\n        Instructs the cmdlet to overwrite the destination file if it already exists\n        \n    .EXAMPLE\n        PS C:\\> Restore-D365WebConfig -Force\n        \n        Will restore the web.config file, and overwrite the current web.config file in the AOS / IIS folder.\n        It will use the default path \"C:\\Temp\\d365fo.tools\\WebConfigBackup\" as the source directory.\n        It will overwrite the current web.config file.\n        \n        A result set example:\n        \n        Filename   LastModified         File\n        --------   ------------         ----\n        web.config 6/29/2021 7:31:04 PM K:\\AosService\\WebRoot\\web.config\n        \n    .NOTES\n        Tags: DEV, Tier2, DB, Database, Debug, JIT, LCS, Azure DB\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Restore-D365WebConfig {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [string] $Path = $(Join-Path $Script:DefaultTempPath \"WebConfigBackup\"),\n\n        [switch] $Force\n    )\n\n    begin {\n        if ($Path -like \"*web.config\") {\n            $sourceFile = $Path\n        }\n        else {\n            $sourceFile = $(Join-Path -Path $Path -ChildPath $Script:WebConfig)\n        }\n    }\n    \n    process {\n\n        if (-not (Test-PathExists -Path $sourceFile -Type Leaf)) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n    \n        $destinationFile = $(Join-Path -Path $Script:AOSPath -ChildPath $Script:WebConfig)\n\n        if (-not $Force) {\n            if ((-not (Test-PathExists -Path $destinationFile -Type Leaf -ShouldNotExist -ErrorAction SilentlyContinue -WarningAction SilentlyContinue))) {\n                Write-PSFMessage -Level Host -Message \"The <c='em'>$destinationFile</c> already exists. Consider changing the <c='em'>destination</c> path or set the <c='em'>Force</c> parameter to overwrite the file.\"\n                return\n            }\n        }\n\n        Write-PSFMessage -Level Verbose -Message \"Copying from: $sourceFile\" -Target $item\n        Copy-Item -Path $sourceFile -Destination $destinationFile -Force:$Force -PassThru | Select-PSFObject \"Name as Filename\", \"LastWriteTime as LastModified\", \"Fullname as File\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/send-d365broadcastmessage.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Send broadcast message to online users in D365FO\n        \n    .DESCRIPTION\n        Utilize the same messaging framework available from LCS and send a broadcast message to all online users in the environment\n        \n    .PARAMETER Tenant\n        Azure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to send a message to\n        \n    .PARAMETER URL\n        URL / URI for the D365FO environment you want to send a message to\n        \n    .PARAMETER ClientId\n        The ClientId obtained from the Azure Portal when you created a Registered Application\n        \n    .PARAMETER ClientSecret\n        The ClientSecret obtained from the Azure Portal when you created a Registered Application\n        \n    .PARAMETER TimeZone\n        Id of the Time Zone your environment is running in\n        \n        You might experience that the local VM running the D365FO is running another Time Zone than the computer you are running this cmdlet from\n        \n        All available .NET Time Zones can be traversed with tab for this parameter\n        \n        The default value is \"UTC\"\n        \n    .PARAMETER StartTime\n        The time and date you want the message to be displayed for the users\n        \n        Default value is NOW\n        \n        The specified StartTime will always be based on local Time Zone. If you specify a different Time Zone than the local computer is running, the start and end time will be calculated based on your selection.\n        \n    .PARAMETER EndingInMinutes\n        Specify how many minutes into the future you want this message / maintenance window to last\n        \n        Default value is 60 minutes\n        \n        The specified StartTime will always be based on local Time Zone. If you specify a different Time Zone than the local computer is running, the start and end time will be calculated based on your selection.\n        \n    .PARAMETER OnPremise\n        Specify if environnement is an D365 OnPremise\n        \n        Default value is \"Not set\" (= Cloud Environnement)\n        \n    .EXAMPLE\n        PS C:\\> Send-D365BroadcastMessage\n        \n        This will send a message to all active users that are working on default D365FO environment.\n        \n        See the RELATED LINKS section for the supporting cmdlets needed to store a default configuration.\n        \n    .EXAMPLE\n        PS C:\\> Send-D365BroadcastMessage -Tenant \"e674da86-7ee5-40a7-b777-1111111111111\" -URL \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" -ClientId \"dea8d7a9-1602-4429-b138-111111111111\" -ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\"\n        \n        This will send a message to all active users that are working on the D365FO environment located at \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\".\n        It will authenticate against the Azure Active Directory with the \"e674da86-7ee5-40a7-b777-1111111111111\" guid.\n        It will use the ClientId \"dea8d7a9-1602-4429-b138-111111111111\" and ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\" go get access to the environment.\n        It will use the default value \"UTC\" Time Zone for converting the different time and dates.\n        It will use the default start time which is NOW.\n        It will use the default end time which is 60 minutes.\n        \n    .EXAMPLE\n        PS C:\\> Send-D365BroadcastMessage -OnPremise -Tenant \"https://adfs.local/adfs\" -URL \"https://ax-sandbox.d365fo.local\" -ClientId \"dea8d7a9-1602-4429-b138-111111111111\" -ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\"\n        \n        This will send a message to all active users that are working on the D365FO OnPremise environment located at \"https://ax-sandbox.d365fo.local\".\n        It will authenticate against Local ADFS with the \"https://adfs.local/adfs\" path\n        It will use the ClientId \"dea8d7a9-1602-4429-b138-111111111111\" and ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\" go get access to the environment.\n        It will use the default value \"UTC\" Time Zone for converting the different time and dates.\n        It will use the default start time which is NOW.\n        It will use the default end time which is 60 minutes.\n        \n    .NOTES\n        \n        The specified StartTime will always be based on local Time Zone. If you specify a different Time Zone than the local computer is running, the start and end time will be calculated based on your selection.\n        \n        For OnPremise environnement use -OnPremise flag to added \"namespaces/AXSF\" path to D365 URL and allow to get token from local ADFS server\n        \n        Tags: Servicing, Message, Users, Environment\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n    .LINK\n        Add-D365BroadcastMessageConfig\n        \n    .LINK\n        Clear-D365ActiveBroadcastMessageConfig\n        \n    .LINK\n        Get-D365ActiveBroadcastMessageConfig\n        \n    .LINK\n        Get-D365BroadcastMessageConfig\n        \n    .LINK\n        Remove-D365BroadcastMessageConfig\n        \n    .LINK\n        Set-D365ActiveBroadcastMessageConfig\n        \n#>\n\nfunction Send-D365BroadcastMessage {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [Parameter(Mandatory = $false, Position = 1)]\n        [Alias('$AADGuid')]\n        [string] $Tenant = $Script:BroadcastTenant,\n\n        [Parameter(Mandatory = $false, Position = 2)]\n        [Alias('URI')]\n        [string] $URL = $Script:BroadcastUrl,\n\n        [Parameter(Mandatory = $false, Position = 3)]\n        [string] $ClientId = $Script:BroadcastClientId,\n\n        [Parameter(Mandatory = $false, Position = 4)]\n        [string] $ClientSecret = $Script:BroadcastClientSecret,\n\n        [Parameter(Mandatory = $false, Position = 5)]\n        [string] $TimeZone = $Script:BroadcastTimeZone,\n\n        [Parameter(Mandatory = $false, Position = 6)]\n        [datetime] $StartTime = (Get-Date),\n\n        [Parameter(Mandatory = $false, Position = 7)]\n        [int] $EndingInMinutes = $Script:BroadcastEndingInMinutes,\n\n        [Parameter(Mandatory = $false, Position = 8)]\n        [switch] $OnPremise = $Script:BroadcastOnPremise\n    )\n\n    $URL = $URL -replace \"/$\", \"\"\n\n    $bearerParms = @{\n        Resource     = $URL\n        ClientId     = $ClientId\n        ClientSecret = $ClientSecret\n    }\n\n    if ($OnPremise) {\n        $bearerParms.AuthProviderUri = \"$Tenant/oauth2/token\"\n    }\n    else {\n        $bearerParms.AuthProviderUri = \"https://login.microsoftonline.com/$Tenant/oauth2/token\"\n    }\n\n    $bearer = Invoke-ClientCredentialsGrant @bearerParms | Get-BearerToken\n\n    $headerParms = @{\n        URL         = $URL\n        BearerToken = $bearer\n    }\n\n    $headers = New-AuthorizationHeaderBearerToken @headerParms\n\n    [System.UriBuilder] $messageEndpoint = $URL\n\n    if ($OnPremise) {\n        $messageEndpoint.Path = \"namespaces/AXSF/api/services/SysBroadcastMessageServices/SysBroadcastMessageService/AddMessage\"\n    }\n    else {\n        $messageEndpoint.Path = \"api/services/SysBroadcastMessageServices/SysBroadcastMessageService/AddMessage\"\n    }\n\n    $endTime = $StartTime.AddMinutes($EndingInMinutes)\n    \n    $timeZoneFound = Get-TimeZone -InputObject $TimeZone\n\n    if (Test-PSFFunctionInterrupt) { return }\n    \n    $startTimeConverted = [System.TimeZoneInfo]::ConvertTime($startTime, [System.TimeZoneInfo]::Local, $timeZoneFound)\n    $endTimeConverted = [System.TimeZoneInfo]::ConvertTime($endTime, [System.TimeZoneInfo]::Local, $timeZoneFound)\n\n    $body = @\"\n{\n    \"request\": {\n        \"FromDateTime\": \"$($startTimeConverted.ToString(\"s\"))\",\n        \"ToDateTime\": \"$($endTimeConverted.ToString(\"s\"))\"\n    }\n}\n\"@\n\n    try {\n        [PSCustomObject]@{\n            MessageId = Invoke-RestMethod -Method Post -Uri $messageEndpoint.Uri.AbsoluteUri -Headers $headers -ContentType 'application/json' -Body $body\n        }\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while trying to send a message to the users.\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors.\"\n        return\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365activeazurestorageconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set the active Azure Storage Account configuration\n        \n    .DESCRIPTION\n        Updates the current active Azure Storage Account configuration with a new one\n        \n    .PARAMETER Name\n        The name the Azure Storage Account configuration you want to load into the active Azure Storage Account configuration\n        \n    .PARAMETER ConfigStorageLocation\n        Parameter used to instruct where to store the configuration objects\n        \n        The default value is \"User\" and this will store all configuration for the active user\n        \n        Valid options are:\n        \"User\"\n        \"System\"\n        \n        \"System\" will store the configuration so all users can access the configuration objects\n        \n    .PARAMETER Temporary\n        Instruct the cmdlet to only temporarily override the persisted settings in the configuration storage\n        \n    .EXAMPLE\n        PS C:\\> Set-D365ActiveAzureStorageConfig -Name \"UAT-Exports\"\n        \n        This will import the \"UAT-Exports\" set from the Azure Storage Account configurations.\n        It will update the active Azure Storage Account configuration.\n        \n    .EXAMPLE\n        PS C:\\> Set-D365ActiveAzureStorageConfig -Name \"UAT-Exports\" -ConfigStorageLocation \"System\"\n        \n        This will import the \"UAT-Exports\" set from the Azure Storage Account configurations.\n        It will update the active Azure Storage Account configuration.\n        The data will be stored in the system wide configuration storage, which makes it accessible from all users.\n        \n    .EXAMPLE\n        PS C:\\> Set-D365ActiveAzureStorageConfig -Name \"UAT-Exports\" -Temporary\n        \n        This will import the \"UAT-Exports\" set from the Azure Storage Account configurations.\n        It will update the active Azure Storage Account configuration.\n        The update will only last for the rest of this PowerShell console session.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n        You will have to run the Initialize-D365Config cmdlet first, before this will be capable of working.\n        \n        You will have to run the Add-D365AzureStorageConfig cmdlet at least once, before this will be capable of working.\n        \n#>\nfunction Set-D365ActiveAzureStorageConfig {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [string] $Name,\n\n        [ValidateSet('User', 'System')]\n        [string] $ConfigStorageLocation = \"User\",\n        \n        [switch] $Temporary\n    )\n\n    $configScope = Test-ConfigStorageLocation -ConfigStorageLocation $ConfigStorageLocation\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    $azureStorageConfigs = [hashtable] (Get-PSFConfigValue -FullName \"d365fo.tools.azure.storage.accounts\")\n\n    if (-not ($azureStorageConfigs.ContainsKey($Name))) {\n        Write-PSFMessage -Level Host -Message \"An Azure Storage Account with that name <c='em'>doesn't exists</c>.\"\n        Stop-PSFFunction -Message \"Stopping because an Azure Storage Account with that name doesn't exists.\"\n        return\n    }\n    else {\n        $azureDetails = $azureStorageConfigs[$Name]\n\n        Set-PSFConfig -FullName \"d365fo.tools.active.azure.storage.account\" -Value $azureDetails\n        if (-not $Temporary) { Register-PSFConfig -FullName \"d365fo.tools.active.azure.storage.account\"  -Scope $configScope }\n        \n        Update-AzureStorageVariables\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365activebroadcastmessageconfig.ps1",
    "content": "﻿\n<#\n        \n    .SYNOPSIS\n        Set the active broadcast message configuration\n        \n    .DESCRIPTION\n        Updates the current active broadcast message configuration with a new one\n        \n    .PARAMETER Name\n        Name of the broadcast message configuration you want to load into the active broadcast message configuration\n        \n    .PARAMETER Temporary\n        Instruct the cmdlet to only temporarily override the persisted settings in the configuration store\n        \n    .EXAMPLE\n        PS C:\\> Set-D365ActiveBroadcastMessageConfig -Name \"UAT\"\n        \n        This will set the broadcast message configuration named \"UAT\" as the active configuration.\n        \n    .NOTES\n        Tags: Servicing, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret, OnPremise\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n    .LINK\n        Add-D365BroadcastMessageConfig\n        \n    .LINK\n        Clear-D365ActiveBroadcastMessageConfig\n        \n    .LINK\n        Get-D365ActiveBroadcastMessageConfig\n        \n    .LINK\n        Get-D365BroadcastMessageConfig\n        \n    .LINK\n        Remove-D365BroadcastMessageConfig\n        \n    .LINK\n        Send-D365BroadcastMessage\n        \n#>\n\nfunction Set-D365ActiveBroadcastMessageConfig {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [Parameter(Mandatory = $true, Position = 1)]\n        [string] $Name,\n\n        [switch] $Temporary\n    )\n\n    if($Name -match '\\*') {\n        Write-PSFMessage -Level Host -Message \"The name cannot contain <c='em'>wildcard character</c>.\"\n        Stop-PSFFunction -Message \"Stopping because the name contains wildcard character.\"\n        return\n    }\n\n    if (-not ((Get-PSFConfig -FullName \"d365fo.tools.broadcast.*.name\").Value -contains $Name)) {\n        Write-PSFMessage -Level Host -Message \"A broadcast message configuration with that name <c='em'>doesn't exists</c>.\"\n        Stop-PSFFunction -Message \"Stopping because a broadcast message configuration with that name doesn't exists.\"\n        return\n    }\n\n    Set-PSFConfig -FullName \"d365fo.tools.active.broadcast.message.config.name\" -Value $Name\n    if (-not $Temporary) { Register-PSFConfig -FullName \"d365fo.tools.active.broadcast.message.config.name\"  -Scope UserDefault }\n\n    Update-BroadcastVariables\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365admin.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Powershell implementation of the AdminProvisioning tool\n        \n    .DESCRIPTION\n        Cmdlet using the AdminProvisioning tool from D365FO\n        \n    .PARAMETER AdminSignInName\n        Email for the Admin\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Set-D365Admin \"claire@contoso.com\"\n        \n        This will provision claire@contoso.com as administrator for the environment\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        Author: Mark Furrer (@devax_mf)\n#>\nfunction Set-D365Admin {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        \n        [Parameter(Mandatory = $true, Position = 1)]\n        [Alias('Email')]\n        [String]$AdminSignInName,\n\n        [Parameter(Mandatory = $false, Position = 2)]\n        [string]$DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Mandatory = $false, Position = 3)]\n        [string]$DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false, Position = 4)]\n        [string]$SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false, Position = 5)]\n        [string]$SqlPwd = $Script:DatabaseUserPassword,\n\n        [switch] $EnableException\n\n    )\n\n    if (-not ($script:IsAdminRuntime)) {\n        Write-PSFMessage -Level Host -Message \"The cmdlet needs <c='em'>administrator permission</c> (Run As Administrator) to be able to update the configuration. Please start an <c='em'>elevated</c> session and run the cmdlet again.\"\n        Stop-PSFFunction -Message \"Stopping because the function is not run elevated\"\n        return\n    }\n\n    Set-AdminUser $AdminSignInName $DatabaseServer $DatabaseName $SqlUser $SqlPwd\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365azcopypath.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set the path for AzCopy.exe\n        \n    .DESCRIPTION\n        Update the path where the module will be looking for the AzCopy.exe executable\n        \n    .PARAMETER Path\n        Path to the AzCopy.exe\n        \n    .EXAMPLE\n        PS C:\\> Invoke-D365InstallAzCopy -Path \"C:\\temp\\d365fo.tools\\AzCopy\\AzCopy.exe\"\n        \n        This will update the path for the AzCopy.exe in the modules configuration\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Set-D365AzCopyPath {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $Path\n    )\n\n    if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    Set-PSFConfig -FullName \"d365fo.tools.path.azcopy\" -Value $Path\n    Register-PSFConfig -FullName \"d365fo.tools.path.azcopy\"\n    \n    Update-ModuleVariables\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365clickoncetrustprompt.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set the ClickOnce needed configuration\n        \n    .DESCRIPTION\n        Creates the needed registry keys and values for ClickOnce to work on the machine\n        \n    .EXAMPLE\n        PS C:\\> Set-D365ClickOnceTrustPrompt\n        \n        This will create / or update the current ClickOnce configuration.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Set-D365ClickOnceTrustPrompt {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param ( )\n    \n    begin { }\n    \n    process {\n        Write-PSFMessage -Level Verbose -Message \"Testing if the registry key exists or not\"\n\n        if (-not (Test-Path -Path \"HKLM:\\SOFTWARE\\MICROSOFT\\.NETFramework\\Security\\TrustManager\\PromptingLevel\")) {\n            Write-PSFMessage -Level Verbose -Message \"Registry key was not found. Will create it now.\"\n            $null = New-Item -Path \"HKLM:\\SOFTWARE\\MICROSOFT\\.NETFramework\\Security\\TrustManager\" -Name \"PromptingLevel\" -Force\n        }\n        \n        Write-PSFMessage -Level Verbose -Message \"Setting all necessary registry keys.\"\n\n        Set-ItemProperty -Path \"HKLM:\\SOFTWARE\\MICROSOFT\\.NETFramework\\Security\\TrustManager\\PromptingLevel\" -Name \"UntrustedSites\" -Type STRING -Value \"Disabled\" -Force\n        Set-ItemProperty -Path \"HKLM:\\SOFTWARE\\MICROSOFT\\.NETFramework\\Security\\TrustManager\\PromptingLevel\" -Name \"Internet\" -Type STRING -Value \"Enabled\" -Force\n        Set-ItemProperty -Path \"HKLM:\\SOFTWARE\\MICROSOFT\\.NETFramework\\Security\\TrustManager\\PromptingLevel\" -Name \"MyComputer\" -Type STRING -Value \"Enabled\" -Force\n        Set-ItemProperty -Path \"HKLM:\\SOFTWARE\\MICROSOFT\\.NETFramework\\Security\\TrustManager\\PromptingLevel\" -Name \"LocalIntranet\" -Type STRING -Value \"Enabled\" -Force\n        Set-ItemProperty -Path \"HKLM:\\SOFTWARE\\MICROSOFT\\.NETFramework\\Security\\TrustManager\\PromptingLevel\" -Name \"TrustedSites\" -Type STRING -Value \"Enabled\" -Force\n    }\n    \n    end { }\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365defaultmodelfornewprojects.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set the default model used creating new projects in Visual Studio\n        \n    .DESCRIPTION\n        Set the registered default model that is used across all new projects that are created inside Visual Studio when working with D365FO project types\n        \n        It will backup the current \"DynamicsDevConfig.xml\" file, for you to revert the changes if anything should go wrong\n        \n    .PARAMETER Module\n        The name of the module / model that you want to be the default model for all new projects used inside Visual Studio when working with D365FO project types\n        \n    .EXAMPLE\n        PS C:\\> Set-D365DefaultModelForNewProjects -Model \"FleetManagement\"\n        \n        This will update the current default module registered in the \"DynamicsDevConfig.xml\" file.\n        This file is located in Documents\\Visual Studio Dynamics 365\\ or in Documents\\Visual Studio 2015\\Settings\\ depending on the version.\n        It will backup the current \"DynamicsDevConfig.xml\" file.\n        It will replace the value inside the \"DefaultModelForNewProjects\" tag.\n        \n    .NOTES\n        Tag: Model, Models, Development, Default Model, Module, Project\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        The work for this cmdlet / function was inspired by Robin Kretzschmar (@DarkSmile92) blog post about changing the default model.\n        \n        The direct link for his blog post is: https://robscode.onl/d365-set-default-model-for-new-projects/\n        \n        His main blog can found here: https://robscode.onl/\n        \n#>\n\nfunction Set-D365DefaultModelForNewProjects {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]\n        [Alias('Model')]\n        [string] $Module\n    )\n\n    begin {\n        $filePath = \"$env:UserProfile\\Documents\\Visual Studio Dynamics 365\\DynamicsDevConfig.xml\"\n        if (-not (Test-PathExists -Path $filePath -Type Leaf)) {\n            $filePath = \"$env:UserProfile\\Documents\\Visual Studio 2015\\Settings\\DynamicsDevConfig.xml\"\n        }\n\n        if (-not (Test-PathExists -Path $filePath -Type Leaf)) { return }\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n\n        Backup-D365DevConfig\n\n        $namespace = @{ns = \"http://schemas.microsoft.com/dynamics/2012/03/development/configuration\" }\n\n        $xmlDoc = [xml] (Get-Content -Path $filePath)\n        $defaultModel = Select-Xml -Xml $xmlDoc -XPath \"/ns:DynamicsDevConfig/ns:DefaultModelForNewProjects\" -Namespace $namespace\n\n        $oldValue = $defaultModel.Node.InnerText\n\n        Write-PSFMessage -Level Verbose -Message \"Old value found in the file was: $oldValue\" -Target $oldValue\n\n        $defaultModel.Node.InnerText = $Module\n        $xmlDoc.Save($filePath)\n    }\n\n    end {\n        Get-D365DefaultModelForNewProjects\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365favoritebookmark.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Enable the favorite bar and add an URL\n        \n    .DESCRIPTION\n        Enable the favorite bar in Edge & Chrome and put in the URL as a favorite/bookmark\n        \n    .PARAMETER URL\n        The URL of the shortcut you want to add to the favorite bar\n        \n    .PARAMETER D365FO\n        Instruct the cmdlet that you want the populate the D365FO favorite entry based on the URL provided\n        \n    .PARAMETER AzureDevOps\n        Instruct the cmdlet that you want the populate the AzureDevOps favorite entry based on the URL provided\n        \n    .EXAMPLE\n        PS C:\\> Set-D365FavoriteBookmark -Url \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\"\n        \n        This will add the \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" to the favorite bar, enable the favorite bar and lock it.\n        This will be interpreted as the using the -D365FO parameter also, because that is the expected behavior.\n        \n    .EXAMPLE\n        PS C:\\> Set-D365FavoriteBookmark -Url \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" -D365FO\n        \n        This will add the \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" to the favorite bar, enable the favorite bar and lock it.\n        The bookmark will be mapped as the one for the Dynamics 365 Finance & Operations instance.\n        \n    .EXAMPLE\n        PS C:\\> Set-D365FavoriteBookmark -Url \"https://CUSTOMERNAME.visualstudio.com/\" -AzureDevOps\n        \n        This will add the \"https://CUSTOMERNAME.visualstudio.com/\" to the favorite bar, enable the favorite bar and lock it.\n        The bookmark will be mapped as the one for the Azure DevOps instance.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365Url | Set-D365FavoriteBookmark\n        \n        This will get the URL from the environment and add that to the favorite bar, enable the favorite bar and lock it.\n        This will be interpreted as the using the -D365FO parameter also, because that is the expected behavior.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Set-D365FavoriteBookmark {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding(DefaultParameterSetName = \"D365FO\")]\n    param (\n        [Parameter(ValueFromPipelineByPropertyName = $true)]\n        [string] $URL,\n\n        [Parameter(Mandatory = $false, ParameterSetName = \"D365FO\")]\n        [switch] $D365FO,\n\n        [Parameter(Mandatory = $false, ParameterSetName = \"AzureDevOps\")]\n        [switch] $AzureDevOps\n    )\n    \n    begin {\n    }\n    \n    process {\n        if ($PSCmdlet.ParameterSetName -eq \"D365FO\") {\n            $name = \"D365FO\"\n        }\n        else {\n            $name = \"AzureDevOps\"\n        }\n\n        # Is edge installed?\n        $pathEdgeBase = \"$($env:LOCALAPPDATA)\\Microsoft\\Edge\\User Data\\Default\"\n        \n        if (Test-PathExists -Path $pathEdgeBase -Type Container) {\n            Set-BrowserBookmark -PathBrowser $pathEdgeBase -Uri $URL -Name $name\n        }\n\n        # Is chrome installed?\n        $pathChromeBase = \"$($env:LOCALAPPDATA)\\Google\\Chrome\\User Data\\Default\"\n\n        if (Test-PathExists -Path $pathChromeBase -Type Container) {\n            Set-BrowserBookmark -PathBrowser $pathChromeBase -Uri $URL -Name $name\n        }\n    }\n    \n    end {\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365flightservicecatalogid.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set the FlightingServiceCatalogID\n        \n    .DESCRIPTION\n        Set the FlightingServiceCatalogID element in the web.config file used by D365FO\n        \n    .PARAMETER AosServiceWebRootPath\n        Path to the root folder where to locate the web.config file\n        \n    .PARAMETER FlightServiceCatalogId\n        Flighting catalog ID to be set\n        \n    .EXAMPLE\n        PS C:\\> Set-D365FlightServiceCatalogId\n        \n        This will set the FlightingServiceCatalogID element the web.config to the default value \"12719367\".\n        \n    .NOTES\n        Tags: Flight, Flighting\n        \n        Author: Frank Hüther(@FrankHuether))\n        \n        The DataAccess.FlightingServiceCatalogID element must already exist in the web.config file, which is expected to be the case in newer environments.\n        https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages#features-flighted-in-data-management-and-enabling-flighted-features\n#>\n\nfunction Set-D365FlightServiceCatalogId {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [string]$FlightServiceCatalogId = \"12719367\",\n        \n        [string]$AosServiceWebRootPath = $Script:AOSPath\n    )\n\n    try {\n        $WebConfigFile = Join-Path -Path $AosServiceWebRootPath -ChildPath $Script:WebConfig\n        \n        Write-PSFMessage -Level Verbose -Message \"Retrieve the FlightingServiceCatalogID\" -Target $WebConfigFile\n\n        [xml]$WebConfigContents = Get-Content $WebConfigFile\n        $FlightServiceNode = $WebConfigContents.SelectSingleNode(\"/configuration/appSettings/add[@key='DataAccess.FlightingServiceCatalogID']/@value\")\n        \n        if($null -eq $FlightServiceNode){\n            Write-PSFMessage -Level Host -Message \"The <c='em'>DataAccess.FlightingServiceCatalogID</c> child element under the <c='em'>AppSettings</c> element is missing. See <c='em'>https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages#features-flighted-in-data-management-and-enabling-flighted-features</c> for details.\"\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n\n        $FlightServiceNode.Value = $FlightServiceCatalogId\n\n        Write-PSFMessage -Level Verbose -Message \"Write the FlightingServiceCatalogID\" -Target $WebConfigFile\n        $WebConfigContents.Save($WebConfigFile)\n        \n        Write-PSFMessage -Level Verbose -Message \"New FlightingServiceCatalogID: $($FlightServiceNode.Value)\" -Target $WebConfigFile\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while updating the web.config file\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365lcsapiconfig.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set the LCS configuration details\n        \n    .DESCRIPTION\n        Set the LCS configuration details and save them into the configuration store\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER ClientId\n        The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER ActiveTokenExpiresOn\n        The point in time where the current bearer token will expire\n        \n        The time is measured in Unix Time, total seconds since 1970-01-01\n        \n    .PARAMETER RefreshToken\n        The Refresh Token that you want to use for the authentication process\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER Temporary\n        Instruct the cmdlet to only temporarily override the persisted settings in the configuration storage\n        \n    .EXAMPLE\n        PS C:\\> Set-D365LcsApiConfig -ProjectId 123456789 -ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" -BearerToken \"JldjfafLJdfjlfsalfd...\" -ActiveTokenExpiresOn 1556909205 -RefreshToken \"Tsdljfasfe2j32324\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will set the LCS API configuration.\n        The ProjectId 123456789 will be saved as the default ProjectId for all cmdlets that will interact with LCS, if they require a ProjectId.\n        The ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" will be saved as the default ClientId for all cmdlets that will interact with LCS, if they require a ClientId.\n        The BearerToken \"JldjfafLJdfjlfsalfd...\" will be saved as the default BearerToken. Remember the BearerToken will expire, so you should fill in the ActiveTokenExpiresOn and RefreshToken parameters also.\n        The ActiveTokenExpiresOn 1556909205 will be saved to assist the module in determine whether the BearerToken is still valid or not.\n        The RefreshToken \"Tsdljfasfe2j32324\" will be saved as the default RefreshToken for all cmdlets that will interact with tokens.\n        The LcsApiUri \"https://lcsapi.lcs.dynamics.com\" will be saved as the default LCS HTTP endpoint for all cmdlets that will interact with LCS.\n        \n    .EXAMPLE\n        PS C:\\> Get-D365LcsApiToken -Username \"serviceaccount@domain.com\" -Password \"TopSecretPassword\" | Set-D365LcsApiConfig\n        \n        This will obtain a valid OAuth 2.0 access token from Azure Active Directory and save the needed details.\n        The Username \"serviceaccount@domain.com\" and Password \"TopSecretPassword\" is used in the OAuth 2.0 Grant Flow, to approved that the application should impersonate like \"serviceaccount@domain.com\".\n        The output object received from Get-D365LcsApiToken is piped directly to Set-D365LcsApiConfig.\n        Set-D365LcsApiConfig will save the access_token(BearerToken), refresh_token(RefreshToken) and expires_on(ActiveTokenExpiresOn).\n        \n        These values will then be available as default values for all LCS cmdlets across the module.\n        \n        You can validate the current default values by calling Get-D365LcsApiConfig.\n        \n    .NOTES\n        Tags: Environment, Url, Config, Configuration, LCS, Upload, ClientId\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Set-D365LcsApiConfig {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    [OutputType()]\n    param(\n        [int] $ProjectId,\n\n        [string] $ClientId,\n\n        [Parameter(ValueFromPipelineByPropertyName = $true)]\n        [Alias('access_token')]\n        [Alias('AccessToken')]\n        [string] $BearerToken,\n\n        [Parameter(ValueFromPipelineByPropertyName = $true)]\n        [Alias('expires_on')]\n        [long] $ActiveTokenExpiresOn,\n\n        [Parameter(ValueFromPipelineByPropertyName = $true)]\n        [Alias('refresh_token')]\n        [string] $RefreshToken,\n\n        [Parameter(ValueFromPipelineByPropertyName = $true)]\n        [Alias('resource')]\n        [string] $LcsApiUri = \"https://lcsapi.lcs.dynamics.com\",\n        \n        [switch] $Temporary\n\n\n    )\n\n    process {\n        #The ':keys' label is used to have a continue inside the switch statement itself\n        :keys foreach ($key in $PSBoundParameters.Keys) {\n        \n            $configurationValue = $PSBoundParameters.Item($key)\n            $configurationName = $key.ToLower()\n            $fullConfigName = \"\"\n\n            Write-PSFMessage -Level Verbose -Message \"Working on $key with $configurationValue\" -Target $configurationValue\n        \n            switch ($key) {\n                \"Temporary\" {\n                    continue keys\n                }\n\n                Default {\n                    $fullConfigName = \"d365fo.tools.lcs.$configurationName\"\n                }\n            }\n\n            Write-PSFMessage -Level Verbose -Message \"Setting $fullConfigName to $configurationValue\" -Target $configurationValue\n        \n            Set-PSFConfig -FullName $fullConfigName -Value $configurationValue\n            if (-not $Temporary) { Register-PSFConfig -FullName $fullConfigName -Scope UserDefault }\n        }\n\n        Update-LcsApiVariables\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365nugetpath.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set the path for nuget.exe\n        \n    .DESCRIPTION\n        Update the path where the module will be looking for the nuget.exe executable\n        \n    .PARAMETER Path\n        Path to the nuget.exe\n        \n    .EXAMPLE\n        PS C:\\> Set-D365NugetPath -Path \"C:\\temp\\d365fo.tools\\nuget\\nuget.exe\"\n        \n        This will update the path for the nuget.exe in the modules configuration\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Set-D365NugetPath {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $Path\n    )\n\n    if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    Set-PSFConfig -FullName \"d365fo.tools.path.nuget\" -Value $Path\n    Register-PSFConfig -FullName \"d365fo.tools.path.nuget\"\n\n    Update-ModuleVariables\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365offlineauthenticationadminemail.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Sets the offline administrator e-mail\n        \n    .DESCRIPTION\n        Sets the registered offline administrator in the \"DynamicsDevConfig.xml\" file located in the default Package Directory\n        \n    .PARAMETER Email\n        The desired email address of the to be offline administrator\n        \n    .EXAMPLE\n        PS C:\\> Set-D365OfflineAuthenticationAdminEmail -Email \"admin@contoso.com\"\n        \n        Will update the Offline Administrator E-mail address in the DynamicsDevConfig.xml file with \"admin@contoso.com\"\n        \n    .NOTES\n        This cmdlet is inspired by the work of \"Sheikh Sohail Hussain\" (twitter: @SSohailHussain)\n        \n        His blog can be found here:\n        http://d365technext.blogspot.com\n        \n        The specific blog post that we based this cmdlet on can be found here:\n        http://d365technext.blogspot.com/2018/07/offline-authentication-admin-email.html\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Set-D365OfflineAuthenticationAdminEmail {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 1 )]\n        [string] $Email\n    )\n\n    if (-not ($script:IsAdminRuntime)) {\n        Write-PSFMessage -Level Host -Message \"The cmdlet needs <c='em'>administrator permission</c> (Run As Administrator) to be able to update the configuration. Please start an <c='em'>elevated</c> session and run the cmdlet again.\"\n        Stop-PSFFunction -Message \"Stopping because the function is not run elevated\"\n        return\n    }\n\n    $filePath = Join-Path (Join-Path $Script:PackageDirectory \"bin\") \"DynamicsDevConfig.xml\"\n\n    if (-not (Test-PathExists -Path $filePath -Type Leaf)) {return}\n\n    $namespace = @{ns=\"http://schemas.microsoft.com/dynamics/2012/03/development/configuration\"}\n    $xmlDoc = [xml] (Get-Content -Path $filePath)\n    $OfflineAuthAdminEmail = Select-Xml -Xml $xmlDoc -XPath \"/ns:DynamicsDevConfig/ns:OfflineAuthenticationAdminEmail\"  -Namespace $namespace\n\n    $oldValue = $OfflineAuthAdminEmail.Node.InnerText\n    \n    Write-PSFMessage -Level Verbose -Message \"Old value found in the file was: $oldValue\" -Target $oldValue\n\n    $OfflineAuthAdminEmail.Node.InnerText = $Email\n    $xmlDoc.Save($filePath)\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365rsatconfiguration.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set different RSAT configuration values\n        \n    .DESCRIPTION\n        Update different RSAT configuration values while using the tool\n        \n    .PARAMETER LogGenerationEnabled\n        Will set the LogGeneration property\n        \n        $true will make RSAT start generating logs\n        $false will stop RSAT from generating logs\n        \n    .PARAMETER VerboseSnapshotsEnabled\n        Will set the VerboseSnapshotsEnabled property\n        \n        $true will make RSAT start generating snapshots and store related details\n        $false will stop RSAT from generating snapshots and store related details\n        \n    .PARAMETER AddOperatorFieldsToExcelValidationEnabled\n        Will set the AddOperatorFieldsToExcelValidation property\n        \n        $true will make RSAT start adding the operation options in the excel parameter file\n        $false will stop RSAT from adding the operation options in the excel parameter file\n        \n    .PARAMETER RSATConfigFilename\n        Specifies the file name of the RSAT configuration file. Default is 'Microsoft.Dynamics.RegressionSuite.WpfApp.exe.config'\n        If you are using an older version of RSAT, you might need to change this to 'Microsoft.Dynamics.RegressionSuite.WindowsApp.exe.config'\n        \n    .EXAMPLE\n        PS C:\\> Set-D365RsatConfiguration -LogGenerationEnabled $true\n        \n        This will enable the log generation logic of RSAT.\n        \n    .EXAMPLE\n        PS C:\\> Set-D365RsatConfiguration -VerboseSnapshotsEnabled $true\n        \n        This will enable the snapshot generation logic of RSAT.\n        \n    .EXAMPLE\n        PS C:\\> Set-D365RsatConfiguration -AddOperatorFieldsToExcelValidationEnabled $true\n        \n        This will enable the operator generation logic of RSAT.\n        \n    .NOTES\n        Tags: RSAT, Testing, Regression Suite Automation Test, Regression, Test, Automation, Configuration\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Set-D365RsatConfiguration {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [Parameter(Mandatory = $false)]\n        [bool] $LogGenerationEnabled,\n\n        [Parameter(Mandatory = $false)]\n        [bool] $VerboseSnapshotsEnabled,\n\n        [Parameter(Mandatory = $false)]\n        [bool] $AddOperatorFieldsToExcelValidationEnabled,\n\n        [Parameter(Mandatory = $false)]\n        $RSATConfigFilename = \"Microsoft.Dynamics.RegressionSuite.WpfApp.exe.config\"\n    )\n\n    $configPath = Join-Path $Script:RsatPath $RSATConfigFilename\n\n    if (-not (Test-PathExists -Path $configPath -Type Leaf)) {\n        Write-PSFMessage -Level Critical -Message \"The '$RSATConfigFilename' file could not be found on the system.\"\n        Stop-PSFFunction -Message  \"Stopping because the '$RSATConfigFilename' file could not be located.\"\n        return\n    }\n\n    try {\n        [xml]$xmlConfig = Get-Content $configPath\n\n        if ($PSBoundParameters.Keys -contains \"LogGenerationEnabled\") {\n            $logGenerationAttribute = $xmlConfig.SelectNodes('//appSettings//add[@key=\"LogGeneration\"]')\n            if ($logGenerationAttribute) {\n                $logGenerationAttribute.SetAttribute('value', $LogGenerationEnabled.ToString().ToLower())\n            }\n        }\n\n        if ($PSBoundParameters.Keys -contains \"VerboseSnapshotsEnabled\") {\n            $verboseSnapshotsAttribute = $xmlConfig.SelectNodes('//appSettings//add[@key=\"VerboseSnapshotsEnabled\"]')\n            if ($verboseSnapshotsAttribute) {\n                $verboseSnapshotsAttribute.SetAttribute('value', $VerboseSnapshotsEnabled.ToString().ToLower())\n            }\n        }\n\n        if ($PSBoundParameters.Keys -contains \"AddOperatorFieldsToExcelValidationEnabled\") {\n            $addOperatorFieldsToExcelValidationAttribute = $xmlConfig.SelectNodes('//appSettings//add[@key=\"AddOperatorFieldsToExcelValidation\"]')\n            if ($addOperatorFieldsToExcelValidationAttribute) {\n                $addOperatorFieldsToExcelValidationAttribute.SetAttribute('value', $AddOperatorFieldsToExcelValidationEnabled.ToString().ToLower())\n            }\n        }\n\n        $xmlConfig.Save($configPath)\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while updating the RSAT configuration file\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365rsattier2crypto.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set the needed configuration to work on Tier2+ environments\n        \n    .DESCRIPTION\n        Set the needed registry settings for when you are running RSAT against a Tier2+ environment\n        \n    .EXAMPLE\n        PS C:\\> Set-D365RsatTier2Crypto\n        \n        This will configure the registry to support RSAT against a Tier2+ environment.\n        \n    .NOTES\n        Tags: RSAT, Testing, Regression Suite Automation Test, Regression, Test, Automation, Configuration\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Set-D365RsatTier2Crypto {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n\n    [CmdletBinding()]\n    [OutputType()]\n    param ()\n    \n    if ((Test-Path \"HKLM:\\SOFTWARE\\Wow6432Node\\Microsoft\\.NETFramework\\v4.0.30319\")) {\n        Set-ItemProperty \"HKLM:\\SOFTWARE\\Wow6432Node\\Microsoft\\.NETFramework\\v4.0.30319\" -Name SchUseStrongCrypto -Value 1 -Type dword -Force -Confirm:$false\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365sdpcleanup.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set the cleanup retention period\n        \n    .DESCRIPTION\n        Sets the configured retention period before updates are deleted\n        \n    .PARAMETER NumberOfDays\n        Number of days that deployable software packages should remain on the server\n        \n    .EXAMPLE\n        PS C:\\> Set-D365SDPCleanUp -NumberOfDays 10\n        \n        This will set the retention period to 10 days inside the the registry\n        \n        The cmdlet REQUIRES elevated permissions to run, otherwise it will fail\n        \n    .NOTES\n        This cmdlet is based on the findings from Alex Kwitny (@AlexOnDAX)\n        \n        See his blog for more info:\n        http://www.alexondax.com/2018/04/msdyn365fo-how-to-adjust-your.html\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Set-D365SDPCleanUp {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [int] $NumberOfDays = 30\n    )\n\n    if (-not ($Script:IsAdminRuntime)) {\n        Write-PSFMessage -Level Host -Message \"It seems that you ran this cmdlet <c='em'>non-elevated</c>. Making changes to the registry requires you to run this cmdlet from an elevated console. Please exit the current console and start a new with `\"Run As Administrator`\"\"\n        Stop-PSFFunction -Message \"Stopping because of missing parameters\"\n        return\n    }\n\n    Set-ItemProperty -Path \"HKLM:\\SOFTWARE\\Microsoft\\Dynamics\\Deployment\" -Name \"CutoffDaysForCleanup\" -Type STRING -Value \"$NumberOfDays\" -Force\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365sqlpackagepath.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set the path for SqlPackage.exe\n        \n    .DESCRIPTION\n        Update the path where the module will be looking for the SqlPackage.exe executable\n        \n    .PARAMETER Path\n        Path to the SqlPackage.exe\n        \n    .EXAMPLE\n        PS C:\\> Set-D365SqlPackagePath -Path \"C:\\Program Files\\Microsoft SQL Server\\150\\DAC\\bin\\SqlPackage.exe\"\n        \n        This will update the path for the SqlPackage.exe in the modules configuration\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Set-D365SqlPackagePath {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $Path\n    )\n\n    if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    Set-PSFConfig -FullName \"d365fo.tools.path.sqlpackage\" -Value $Path\n    Register-PSFConfig -FullName \"d365fo.tools.path.sqlpackage\"\n\n    Update-ModuleVariables\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365startpage.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Sets the start page in internet explorer\n        \n    .DESCRIPTION\n        Function for setting the start page in internet explorer\n        \n    .PARAMETER Name\n        Name of the D365 Instance\n        \n    .PARAMETER Url\n        URL of the D365 for Finance & Operations instance that you want to have as your start page\n        \n    .EXAMPLE\n        PS C:\\> Set-D365StartPage -Name 'Demo1'\n        \n        This will update the start page for the current user to \"https://Demo1.cloud.onebox.dynamics.com\"\n        \n    .EXAMPLE\n        PS C:\\> Set-D365StartPage -URL \"https://uat.sandbox.operations.dynamics.com\"\n        \n        This will update the start page for the current user to \"https://uat.sandbox.operations.dynamics.com\"\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Set-D365StartPage() {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param(\n        \n        [Parameter(Mandatory = $true, Position = 1, ParameterSetName = 'Default')]\n        [String] $Name,\n\n        [Parameter(Mandatory = $true, Position = 1, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Url')]\n        [String] $Url\n    )\n   \n    process {\n        $path = 'HKCU:\\Software\\Microsoft\\Internet Explorer\\Main\\'\n        $propName = 'start page'\n    \n        if ($PSBoundParameters.ContainsKey(\"URL\")) {\n            $value = $Url\n        }\n        else {\n            $value = \"https://$Name.cloud.onebox.dynamics.com\"\n        }\n\n        Set-Itemproperty -Path $path -Name $propName -Value $value\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365sysadmin.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set a user to sysadmin\n        \n    .DESCRIPTION\n        Set a user to sysadmin inside the SQL Server\n        \n    .PARAMETER User\n        The user that you want to make sysadmin\n        \n        Most be well formatted server\\user or domain\\user.\n        \n        Default value is: machinename\\administrator\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .EXAMPLE\n        PS C:\\> Set-D365SysAdmin\n        \n        This will configure the local administrator on the machine as a SYSADMIN inside SQL Server\n        \n        For this to run you need to be running it from a elevated console\n        \n    .EXAMPLE\n        PS C:\\> Set-D365SysAdmin -SqlPwd Test123\n        \n        This will configure the local administrator on the machine as a SYSADMIN inside SQL Server.\n        It will logon as the default SqlUser but use the provided SqlPwd.\n        \n        This can be run from a non-elevated console\n        \n    .NOTES\n        Author: Mötz Jensen (@splaxi)\n        \n#>\nfunction Set-D365SysAdmin {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n\n        [Parameter(Mandatory = $false, Position = 1)]\n        [string] $User = \"$env:computername\\administrator\",\n\n        [Parameter(Mandatory = $false, Position = 2)]\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [Parameter(Mandatory = $false, Position = 3)]\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [Parameter(Mandatory = $false, Position = 4)]\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [Parameter(Mandatory = $false, Position = 5)]\n        [string] $SqlPwd = $Script:DatabaseUserPassword\n    )\n\n    $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd\n    }\n    \n    Write-PSFMessage -Level Debug -Message \"Testing if running either elevated or with -SqlPwd set.\"\n    if ((-not ($script:IsAdminRuntime)) -and (-not ($PSBoundParameters.ContainsKey(\"SqlPwd\")))) {\n        Write-PSFMessage -Level Host -Message \"It seems that you ran this cmdlet <c='em'>non-elevated</c> and without the <c='em'>-SqlPwd parameter</c>. If you don't want to supply the -SqlPwd you must run the cmdlet elevated (Run As Administrator) otherwise simply use the -SqlPwd parameter\"\n        Stop-PSFFunction -Message \"Stopping because of missing parameters\"\n        return\n    }\n\n    $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\set-sysadmin.sql\") -join [Environment]::NewLine\n    $commandText = $commandText.Replace('@USER', $User)\n\n    $sqlCommand = Get-SqlCommand @SqlParams\n\n    $sqlCommand.CommandText = $commandText\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n\n        $null = $sqlCommand.ExecuteNonQuery()\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365traceparserfilesize.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Configue a new maximum file size for the TraceParser\n        \n    .DESCRIPTION\n        Change the maximum file size that the TraceParser generates\n        \n    .PARAMETER FileSizeInMB\n        The maximum size that you want to allow the TraceParser file to grow to\n        \n        Original value inside the configuration is 1024 (MB)\n        \n    .PARAMETER Path\n        The path to the TraceParser.config file that you want to edit\n        \n        The default path is: \"\\AosService\\Webroot\\Services\\TraceParserService\\TraceParserService.config\"\n        \n    .EXAMPLE\n        PS C:\\> Set-D365TraceParserFileSize -FileSizeInMB 2048\n        \n        This will configure the maximum TraceParser file to 2048 MB.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Set-D365TraceParserFileSize {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $FileSizeInMB,\n        \n        [string] $Path = (Join-Path $Script:AOSPath \"Services\\TraceParserService\\TraceParserService.config\")\n    )\n\n    if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n    $xmlDoc = [xml] (Get-Content -Path $Path)\n\n    $fileSize = Select-Xml -Xml $xmlDoc -XPath \"/Microsoft.Dynamics.AX.Services.Tracing.TraceParser.Properties.Settings/setting[@name='MaximumEtlFileSizeInMb']/value\"\n    \n    $fileSize.Node.\"#text\" = \"$FileSizeInMB\"\n\n    $xmlDoc.Save($Path)\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365webconfigdatabase.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set the database connection details\n        \n    .DESCRIPTION\n        Overwrite the current database connection details directly in the web.config file\n        \n        Used when you want to connect a DEV box directly to a Tier2 database, and want to debug something that requires better data than usual\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        Obtain when you request JIT (Just-in-Time) access through the LCS portal\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n        Obtain when you request JIT (Just-in-Time) access through the LCS portal\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n        Obtain when you request JIT (Just-in-Time) access through the LCS portal\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n        Obtain when you request JIT (Just-in-Time) access through the LCS portal\n        \n    .PARAMETER Path\n        Path to the web.config file that you want to update with new SQL connection details\n        \n        Default is: \"K:\\AosService\\WebRoot\\web.config\" or what else drive that is recognized by the D365FO components as the service drive\n        \n    .EXAMPLE\n        PS C:\\> Set-D365WebConfigDatabase -DatabaseServer TestServer.database.windows.net -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\"\n        \n        Will overwrite Server, Database, Username and Password directly in the web.config file.\n        It will save all details unencrypted.\n        \n    .NOTES\n        Tags: DEV, Tier2, DB, Database, Debug, JIT, LCS, Azure DB\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Set-D365WebConfigDatabase {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseServer,\n\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseName,\n\n        [Parameter(Mandatory = $true)]\n        [string] $SqlUser,\n\n        [Parameter(Mandatory = $true)]\n        [string] $SqlPwd,\n\n        $Path = $(Join-Path -Path $Script:AOSPath -ChildPath $Script:WebConfig)\n    )\n\n    begin {\n        if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False\n    }\n\n    process {\n        $content = Get-Content -Path $Path -Raw\n\n        $content = $content -replace '<add key=\"DataAccess.Database\" value=\".*\" {0,1}/>', $('<add key=\"DataAccess.Database\" value=\"{0}\" />' -f \"$DatabaseName\")\n        $content = $content -replace '<add key=\"DataAccess.DbServer\" value=\".*\" {0,1}/>', $('<add key=\"DataAccess.DbServer\" value=\"{0}\" />' -f \"$DatabaseServer\")\n        $content = $content -replace '<add key=\"DataAccess.SqlPwd\" value=\".*\" {0,1}/>', $('<add key=\"DataAccess.SqlPwd\" value=\"{0}\" />' -f \"$SqlPwd\")\n        $content = $content -replace '<add key=\"DataAccess.SqlUser\" value=\".*\" {0,1}/>', $('<add key=\"DataAccess.SqlUser\" value=\"{0}\" />' -f \"$SqlUser\")\n\n        [System.IO.File]::WriteAllText($Path, $content, $Utf8NoBomEncoding)\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365webservertype.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set the web server type to be used to run the D365FO instance\n        \n    .DESCRIPTION\n        Set the web server which will be used to run D365FO: Either IIS or IIS Express.\n        Newly deployed development machines will have this set to IIS Express by default.\n        \n        It will backup the current \"DynamicsDevConfig.xml\" file, for you to revert the changes if anything should go wrong.\n        \n        It will look for the file located in the default Package Directory.\n        \n    .PARAMETER RuntimeHostType\n        The type of web server you want to use.\n        \n        Valid options are:\n        \"IIS\"\n        \"IISExpress\"\n        \n    .EXAMPLE\n        PS C:\\> Set-D365WebServerType -RuntimeHostType \"IIS\"\n        \n        This will update the current web server type registered in the \"DynamicsDevConfig.xml\" file.\n        This file is located \"K:\\AosService\\PackagesLocalDirectory\\bin\".\n        It will backup the current \"DynamicsDevConfig.xml\" file.\n        It will replace the value inside the \"RuntimeHostType\" tag.\n        \n    .NOTES\n        Tag: Web Server, IIS, IIS Express, Development\n        \n        Author: Sander Holvoet (@smholvoet)\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Set-D365WebServerType {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]\n        [ValidateSet('IIS', 'IISExpress')]\n        [string] $RuntimeHostType\n    )\n\n    begin {\n        if (-not ($script:IsAdminRuntime)) {\n            Write-PSFMessage -Level Host -Message \"The cmdlet needs <c='em'>administrator permission</c> (Run As Administrator) to be able to update the configuration. Please start an <c='em'>elevated</c> session and run the cmdlet again.\"\n            Stop-PSFFunction -Message \"Stopping because the function is not run elevated\"\n            return\n        }\n    \n        $filePath = Join-Path -Path (Join-Path -Path $Script:PackageDirectory -ChildPath \"bin\") -ChildPath $Script:DevConfig\n    \n        if (-not (Test-PathExists -Path $filePath -Type Leaf)) { return }\n    }\n\n    process {\n        if (Test-PSFFunctionInterrupt) { return }\n\n        $filePathBackup = $filePath.Replace(\".xml\", \".xml$((Get-Date).Ticks)\")\n        Copy-Item -Path $filePath -Destination $filePathBackup -Force\n\n        $namespace = @{ns = \"http://schemas.microsoft.com/dynamics/2012/03/development/configuration\" }\n\n        $xmlDoc = [xml] (Get-Content -Path $filePath)\n        $runtimeHostType = Select-Xml -Xml $xmlDoc -XPath \"/ns:DynamicsDevConfig/ns:RuntimeHostType\" -Namespace $namespace\n\n        $oldValue = $runtimeHostType.Node.InnerText\n\n        Write-PSFMessage -Level Verbose -Message \"Old value found in the file was: $oldValue\" -Target $oldValue\n\n        $runtimeHostType.Node.InnerText = $RuntimeHostType\n        $xmlDoc.Save($filePath)\n    }\n\n    end {\n        Get-D365WebServerType\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/set-d365workstationmode.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set the Workstation mode\n        \n    .DESCRIPTION\n        Set the Workstation mode to enabled or not\n        \n        It is used to enable the tool to run on a personal machine and still be able to call Invoke-D365TableBrowser and Invoke-D365SysRunnerClass\n        \n    .PARAMETER Enabled\n        $True enables the workstation mode while $false deactivated the workstation mode\n        \n    .EXAMPLE\n        PS C:\\> Set-D365WorkstationMode -Enabled $true\n        \n        This will enable the Workstation mode.\n        You will have to restart the powershell session when you switch around.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n        You will have to run the Initialize-D365Config cmdlet first, before this will be capable of working.\n        \n#>\nfunction Set-D365WorkstationMode {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [boolean] $Enabled\n    )\n\n    Set-PSFConfig -FullName \"d365fo.tools.workstation.mode\" -Value $Enabled\n    Register-PSFConfig -FullName \"d365fo.tools.workstation.mode\"\n\n    Write-PSFMessage -Level Host -Message \"Please <c='em'>restart</c> the powershell session / console. This change affects core functionality that <c='em'>requires</c> the module to be <c='em'>reloaded</c>.\"\n}"
  },
  {
    "path": "d365fo.tools/functions/start-d365environment.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Cmdlet to start the different services in a Dynamics 365 Finance & Operations environment\n        \n    .DESCRIPTION\n        Can start all relevant services that is running in a D365FO environment\n        \n    .PARAMETER ComputerName\n        An array of computers that you want to start services on.\n        \n    .PARAMETER All\n        Set when you want to start all relevant services\n        \n        Includes:\n        Aos\n        Batch\n        Financial Reporter\n        \n    .PARAMETER Aos\n        Start the Aos (iis) service\n        \n    .PARAMETER Batch\n        Start the batch service\n        \n    .PARAMETER FinancialReporter\n        Start the financial reporter (Management Reporter 2012) service\n        \n    .PARAMETER DMF\n        Start the Data Management Framework service\n        \n    .PARAMETER OnlyStartTypeAutomatic\n        Instruct the cmdlet to filter out services that are set to manual start or disabled\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .EXAMPLE\n        PS C:\\> Start-D365Environment\n        \n        This will run the cmdlet with the default parameters.\n        Default is \"-All\".\n        This will start all D365FO services on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Start-D365Environment -OnlyStartTypeAutomatic\n        \n        This will start all D365FO services on the machine that are configured for Automatic startup.\n        It will exclude all services that are either manual or disabled in their startup configuration.\n        \n    .EXAMPLE\n        PS C:\\> Start-D365Environment -ShowOriginalProgress\n        \n        This will run the cmdlet with the default parameters.\n        Default is \"-All\".\n        This will start all D365FO services on the machine.\n        The progress of starting the different services will be written to the console / host.\n        \n    .EXAMPLE\n        PS C:\\> Start-D365Environment -All\n        \n        This will start all D365FO services on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Start-D365Environment -Aos -Batch\n        \n        This will start the Aos & Batch D365FO services on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Start-D365Environment -FinancialReporter -DMF\n        \n        This will start the FinancialReporter and DMF services on the machine.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Start-D365Environment {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidDefaultValueSwitchParameter\", \"\")]\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    \n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 1 )]\n        [string[]] $ComputerName = @($env:computername),\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )]\n        [switch] $All = $true,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 2 )]\n        [switch] $Aos,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 3 )]\n        [switch] $Batch,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 4 )]\n        [switch] $FinancialReporter,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 5 )]\n        [switch] $DMF,\n\n        [switch] $OnlyStartTypeAutomatic,\n\n        [switch] $ShowOriginalProgress\n    )\n\n    Import-Module -Name \"WebAdministration\" -Scope \"Local\"\n\n    if ($PSCmdlet.ParameterSetName -eq \"Specific\") {\n        $All = $false\n    }\n\n    if ( (-not ($All)) -and (-not ($Aos)) -and (-not ($Batch)) -and (-not ($FinancialReporter)) -and (-not ($DMF))) {\n        Write-PSFMessage -Level Host -Message \"You have to use at least <c='em'>one switch</c> when running this cmdlet. Please run the cmdlet again.\"\n        Stop-PSFFunction -Message \"Stopping because of missing parameters\"\n        return\n    }\n\n    $warningActionValue = \"SilentlyContinue\"\n    if ($ShowOriginalProgress) { $warningActionValue = \"Continue\" }\n\n    $Params = Get-DeepClone $PSBoundParameters\n    if ($Params.ContainsKey(\"ComputerName\")) { $null = $Params.Remove(\"ComputerName\") }\n    if ($Params.ContainsKey(\"ShowOriginalProgress\")) { $null = $Params.Remove(\"ShowOriginalProgress\") }\n    if ($Params.ContainsKey(\"OnlyStartTypeAutomatic\")) { $null = $Params.Remove(\"OnlyStartTypeAutomatic\") }\n\n    $Services = Get-ServiceList @Params\n\n    $Results = foreach ($server in $ComputerName) {\n        Write-PSFMessage -Level Verbose -Message \"Working against: $server - starting services\"\n        $temp = Get-Service -ComputerName $server -Name $Services -ErrorAction SilentlyContinue\n        \n        if ($OnlyStartTypeAutomatic) {\n            $temp = $temp | Where-Object StartType -eq \"Automatic\"\n        }\n\n        $temp | Start-Service -ErrorAction SilentlyContinue -WarningAction $warningActionValue\n\n        if ($server -eq $env:computername -and ($($temp -join \",\") -like \"*w3svc*\")) {\n            Start-Website -Name \"AOSService\"\n        }\n    }\n\n    $Results = foreach ($server in $ComputerName) {\n        Write-PSFMessage -Level Verbose -Message \"Working against: $server - listing services\"\n        $temp = Get-Service -ComputerName $server -Name $Services -ErrorAction SilentlyContinue\n        \n        if ($OnlyStartTypeAutomatic) {\n            $temp = $temp | Where-Object StartType -eq \"Automatic\"\n        }\n\n        $temp | Select-Object @{Name = \"Server\"; Expression = { $Server } }, Name, Status, StartType, DisplayName\n    }\n\n    Write-PSFMessage -Level Verbose \"Results are: $Results\" -Target ($Results.Name -join \",\")\n\n    $Results | Select-PSFObject -TypeName \"D365FO.TOOLS.Environment.Service\" Server, DisplayName, Status, StartType, Name\n}"
  },
  {
    "path": "d365fo.tools/functions/start-d365environmentv2.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Cmdlet to start the different services in a Dynamics 365 Finance & Operations environment\n        \n    .DESCRIPTION\n        Can start all relevant services that is running in a D365FO environment\n        \n    .PARAMETER All\n        Set when you want to start all relevant services\n        \n        Includes:\n        Aos\n        Batch\n        Financial Reporter\n        Data Management Framework\n        \n    .PARAMETER Aos\n        Start the Aos (iis) service\n        \n    .PARAMETER Batch\n        Start the batch service\n        \n    .PARAMETER FinancialReporter\n        Start the financial reporter (Management Reporter 2012) service\n        \n    .PARAMETER DMF\n        Start the Data Management Framework service\n        \n    .PARAMETER OnlyStartTypeAutomatic\n        Instruct the cmdlet to filter out services that are set to manual start or disabled\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .EXAMPLE\n        PS C:\\> Start-D365EnvironmentV2\n        \n        This will run the cmdlet with the default parameters.\n        Default is \"-All\".\n        This will start all D365FO services on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Start-D365EnvironmentV2 -OnlyStartTypeAutomatic\n        \n        This will start all D365FO services on the machine that are configured for Automatic startup.\n        It will exclude all services that are either manual or disabled in their startup configuration.\n        \n    .EXAMPLE\n        PS C:\\> Start-D365EnvironmentV2 -ShowOriginalProgress\n        \n        This will run the cmdlet with the default parameters.\n        Default is \"-All\".\n        This will start all D365FO services on the machine.\n        The progress of starting the different services will be written to the console / host.\n        \n    .EXAMPLE\n        PS C:\\> Start-D365EnvironmentV2 -All\n        \n        This will start all D365FO services on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Start-D365EnvironmentV2 -Aos -Batch\n        \n        This will start the Aos & Batch D365FO services on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Start-D365EnvironmentV2 -FinancialReporter -DMF\n        \n        This will start the FinancialReporter and DMF services on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Enable-D365Exception\n        PS C:\\> Start-D365EnvironmentV2\n        \n        This will run the cmdlet with the default parameters.\n        Default is \"-All\".\n        This will start all D365FO services on the machine.\n        If a service does not start, it will throw an exception.\n        \n    .NOTES\n        Author: Vincent Verweij (@VincentVerweij)\n        \n#>\nfunction Start-D365EnvironmentV2 {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidDefaultValueSwitchParameter\", \"\")]\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    \n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )]\n        [switch] $All = $true,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 1 )]\n        [switch] $Aos,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 2 )]\n        [switch] $Batch,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 3 )]\n        [switch] $FinancialReporter,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 4 )]\n        [switch] $DMF,\n\n        [switch] $OnlyStartTypeAutomatic,\n\n        [switch] $ShowOriginalProgress\n    )\n\n    Import-Module -Name \"WebAdministration\" -Scope \"Local\"\n\n    if ($PSCmdlet.ParameterSetName -eq \"Specific\") {\n        $All = $false\n    }\n\n    if ( (-not ($All)) -and (-not ($Aos)) -and (-not ($Batch)) -and (-not ($FinancialReporter)) -and (-not ($DMF))) {\n        Write-PSFMessage -Level Host -Message \"You have to use at least <c='em'>one switch</c> when running this cmdlet. Please run the cmdlet again.\"\n        Stop-PSFFunction -Message \"Stopping because of missing parameters\"\n        return\n    }\n\n    $ComputerName = @($env:computername)\n    $warningActionValue = \"SilentlyContinue\"\n    if ($ShowOriginalProgress) { $warningActionValue = \"Continue\" }\n\n    $Params = Get-DeepClone $PSBoundParameters\n    if ($Params.ContainsKey(\"ShowOriginalProgress\")) { $null = $Params.Remove(\"ShowOriginalProgress\") }\n    if ($Params.ContainsKey(\"OnlyStartTypeAutomatic\")) { $null = $Params.Remove(\"OnlyStartTypeAutomatic\") }\n\n    $psItemExceptionsFromStartServices = New-Object -TypeName \"System.Collections.ArrayList\"\n    $didServiceStartThrowException = $false\n\n    $Services = Get-ServiceList @Params\n\n    Write-PSFMessage -Level Verbose -Message \"Working against: $ComputerName - starting services\"\n    $temp = Get-Service -ComputerName $ComputerName -Name $Services -ErrorAction SilentlyContinue\n    \n    if ($OnlyStartTypeAutomatic) {\n        $temp = $temp | Where-Object StartType -eq \"Automatic\"\n    }\n\n    try {\n        $temp | Start-Service -WarningAction $warningActionValue\n    }\n    catch {\n        $didServiceStartThrowException = $true\n        $psItemExceptionsFromStartServices.Add($PSItem.Exception)\n    }\n\n    if (($($temp -join \",\") -like \"*w3svc*\")) {\n        Start-Website -Name \"AOSService\"\n    }\n\n    Write-PSFMessage -Level Verbose -Message \"Working against: $ComputerName - listing services\"\n    $temp = Get-Service -ComputerName $ComputerName -Name $Services -ErrorAction SilentlyContinue\n    \n    if ($OnlyStartTypeAutomatic) {\n        $temp = $temp | Where-Object StartType -eq \"Automatic\"\n    }\n\n    $Results = $temp | Select-Object @{Name = \"Server\"; Expression = { $ComputerName } }, Name, Status, StartType, DisplayName\n\n    Write-PSFMessage -Level Verbose \"Results are: $Results\" -Target ($Results.Name -join \",\")\n\n    $Results | Select-PSFObject -TypeName \"D365FO.TOOLS.Environment.Service\" Server, DisplayName, Status, StartType, Name\n\n    if ($didServiceStartThrowException) {\n        foreach ($psItemException in $psItemExceptionsFromStartServices) {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while starting the service(s) on computer '$($ComputerName)'\" -Exception $psItemException\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/start-d365eventtrace.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Start an Event Trace session\n        \n    .DESCRIPTION\n        Start an Event Trace session with default values to help you getting started\n        \n    .PARAMETER ProviderName\n        Name of the provider(s) you want to have part of your trace\n        \n        Accepts an array/list of provider names\n        \n    .PARAMETER OutputPath\n        Path to the output folder where you want to store the ETL file that will be generated\n        \n        Default path is \"C:\\Temp\\d365fo.tools\\EventTrace\"\n        \n    .PARAMETER SessionName\n        Name that you want the tracing session to have while running the trace\n        \n        Default value is \"d365fo.tools.trace\"\n        \n    .PARAMETER FileName\n        Name of the file that you want the trace to write its output to\n        \n        Default value is \"d365fo.tools.trace.etl\"\n        \n    .PARAMETER OutputFormat\n        The desired output format of the ETL file being outputted from the tracing session\n        \n        Default value is \"bincirc\"\n        \n    .PARAMETER MinBuffer\n        The minimum buffer size in MB that you want the tracing session to work with\n        \n        Default value is 10240\n        \n    .PARAMETER MaxBuffer\n        The maximum buffer size in MB that you want the tracing session to work with\n        \n        Default value is 10240\n        \n    .PARAMETER BufferSizeKB\n        The buffer size in KB that you want the tracing session to work with\n        \n        Default value is 1024\n        \n    .PARAMETER MaxLogFileSizeMB\n        The maximum log file size in MB that you want the tracing session to work with\n        \n        Default value is 4096\n        \n    .EXAMPLE\n        PS C:\\> Start-D365EventTrace -ProviderName \"Microsoft-Dynamics-AX-FormServer\",\"Microsoft-Dynamics-AX-XppRuntime\"\n        \n        This will start a new Event Tracing session with the binary circular output format.\n        It uses \"Microsoft-Dynamics-AX-FormServer\",\"Microsoft-Dynamics-AX-XppRuntime\" as the providernames.\n        It uses the default output folder \"C:\\Temp\\d365fo.tools\\EventTrace\".\n        \n        It will use the default values for the remaining parameters.\n        \n    .EXAMPLE\n        PS C:\\> Start-D365EventTrace -ProviderName \"Microsoft-Dynamics-AX-FormServer\",\"Microsoft-Dynamics-AX-XppRuntime\" -OutputFormat CSV\n        \n        This will start a new Event Tracing session with the comma separated output format.\n        It uses \"Microsoft-Dynamics-AX-FormServer\",\"Microsoft-Dynamics-AX-XppRuntime\" as the providernames.\n        It uses the default output folder \"C:\\Temp\\d365fo.tools\\EventTrace\".\n        \n        It will use the default values for the remaining parameters.\n        \n    .NOTES\n        Tags: ETL, EventTracing, EventTrace\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        This cmdlet/function was inspired by the work of Michael Stashwick (@D365Stuff)\n        \n        He blog is located here: https://www.d365stuff.co/\n        \n        and the blogpost that pointed us in the right direction is located here: https://www.d365stuff.co/trace-batch-jobs-and-more-via-cmd-logman/\n#>\n\nfunction Start-D365EventTrace {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]\n        [string[]] $ProviderName,\n\n        [string] $OutputPath = (Join-Path -Path $Script:DefaultTempPath -ChildPath \"EventTrace\"),\n\n        [string] $SessionName = \"d365fo.tools.trace\",\n\n        [string] $FileName = \"d365fo.tools.trace.etl\",\n\n        [ValidateSet('bin', 'bincirc', 'csv', 'sql', 'tsv')]\n        [string] $OutputFormat = \"bincirc\",\n\n        [Int32] $MinBuffer = 10240,\n\n        [Int32] $MaxBuffer = 10240,\n\n        [Int32] $BufferSizeKB = 1024,\n\n        [Int32] $MaxLogFileSizeMB = 4096\n    )\n    \n    begin {\n        $providers = New-Object System.Collections.Generic.List[string]\n\n        if (-not (Test-PathExists -Path $OutputPath -Type Container -Create)) { return }\n\n        Write-PSFMessage -Level Verbose -Message \"Configuring the permissions on the folder to make sure the Start-Trace command can read the files.\" -Target $OutputPath\n        \n        $propagation = [system.security.accesscontrol.PropagationFlags]\"None\"\n        $inherit = [system.security.accesscontrol.InheritanceFlags]\"ContainerInherit, ObjectInherit\"\n        $accessRule = New-Object  system.security.accesscontrol.filesystemaccessrule(\"BUILTIN\\Users\", \"FullControl\", $inherit, $propagation, \"Allow\")\n        $aclFolder = Get-Acl -Path $OutputPath\n        $aclFolder.AddAccessRule($accessRule)\n        Set-Acl -Path $OutputPath -AclObject $aclFolder\n        \n        $providerListPath = Join-Path -Path $OutputPath -ChildPath \"ProviderList.txt\"\n    }\n    \n    process {\n        foreach ($name in $ProviderName) {\n            Write-PSFMessage -Level Verbose -Message \"Adding the $name to the list of providers.\" -Target $name\n            $providers.Add($name)\n        }\n    }\n    \n    end {\n        Write-PSFMessage -Level Verbose -Message \"Storing the providers in '$providerListPath' as a UTF8 (NON-BOM) file.\" -Target $providerListPath\n\n        $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False\n        [System.IO.File]::WriteAllLines($providerListPath, $($providers.ToArray() -join [System.Environment]::NewLine), $Utf8NoBomEncoding)\n\n        $outputFile = Join-Path -Path $OutputPath -ChildPath $FileName\n\n        Write-PSFMessage -Level Verbose -Message \"Starting the trace now.\"\n        Start-Trace -SessionName $SessionName -OutputFilePath $outputFile -ProviderFilePath $providerListPath -ETS -Format $OutputFormat -MinBuffers $MinBuffer -MaxBuffers $MaxBuffer -BufferSizeInKB $BufferSizeKB -MaxLogFileSizeInMB $MaxLogFileSizeMB\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/stop-d365environment.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Cmdlet to stop the different services in a Dynamics 365 Finance & Operations environment\n        \n    .DESCRIPTION\n        Can stop all relevant services that is running in a D365FO environment\n        \n    .PARAMETER ComputerName\n        An array of computers that you want to stop services on.\n        \n    .PARAMETER All\n        Set when you want to stop all relevant services\n        \n        Includes:\n        Aos\n        Batch\n        Financial Reporter\n        \n    .PARAMETER Aos\n        Stop the Aos (iis) service\n        \n    .PARAMETER Batch\n        Stop the batch service\n        \n    .PARAMETER FinancialReporter\n        Start the financial reporter (Management Reporter 2012) service\n        \n    .PARAMETER DMF\n        Start the Data Management Framework service\n        \n    .PARAMETER Kill\n        Instructs the cmdlet to kill the service(s) that you want to stop\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .EXAMPLE\n        PS C:\\> Stop-D365Environment\n        \n        This will run the cmdlet with the default parameters.\n        Default is \"-All\".\n        This will stop all D365FO services on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Stop-D365Environment -ShowOriginalProgress\n        \n        This will run the cmdlet with the default parameters.\n        Default is \"-All\".\n        This will Stop all D365FO services on the machine.\n        The progress of Stopping the different services will be written to the console / host.\n        \n    .EXAMPLE\n        PS C:\\> Stop-D365Environment -All\n        \n        This will stop all D365FO services on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Stop-D365Environment -Aos -Batch\n        \n        This will stop the Aos & Batch D365FO services on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Stop-D365Environment -FinancialReporter -DMF\n        \n        This will stop the FinancialReporter and DMF services on the machine.\n        \n    .EXAMPLE\n        PS C:\\> Stop-D365Environment -All -Kill\n        \n        This will stop all D365FO services on the machine.\n        It will use the Kill parameter to make sure that the services is stopped.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Stop-D365Environment {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidDefaultValueSwitchParameter\", \"\")]\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    \n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 1 )]\n        [string[]] $ComputerName = @($env:computername),\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )]\n        [switch] $All = $true,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 2 )]\n        [switch] $Aos,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 3 )]\n        [switch] $Batch,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 4 )]\n        [switch] $FinancialReporter,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 5 )]\n        [switch] $DMF,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 6 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 6 )]\n        [switch] $Kill,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 7 )]\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 7 )]\n        [switch] $ShowOriginalProgress\n    )\n\n    if ($PSCmdlet.ParameterSetName -eq \"Specific\") {\n        $All = $false\n    }\n\n    if ((-not ($All)) -and (-not ($Aos)) -and (-not ($Batch)) -and (-not ($FinancialReporter)) -and (-not ($DMF))) {\n        Write-PSFMessage -Level Host -Message \"You have to use at least <c='em'>one switch</c> when running this cmdlet. Please run the cmdlet again.\"\n        Stop-PSFFunction -Message \"Stopping because of missing parameters\"\n        return\n    }\n\n    $warningActionValue = \"SilentlyContinue\"\n    if ($ShowOriginalProgress) { $warningActionValue = \"Continue\" }\n\n    $Params = Get-DeepClone $PSBoundParameters\n    if ($Params.ContainsKey(\"ComputerName\")) { $null = $Params.Remove(\"ComputerName\") }\n    if ($Params.ContainsKey(\"ShowOriginalProgress\")) { $null = $Params.Remove(\"ShowOriginalProgress\") }\n    if ($Params.ContainsKey(\"Kill\")) { $null = $Params.Remove(\"Kill\") }\n\n    $Services = Get-ServiceList @Params\n    \n    $Results = foreach ($server in $ComputerName) {\n        Write-PSFMessage -Level Verbose -Message \"Working against: $server - stopping services\"\n\n        if (-not $Kill) {\n            Get-Service -ComputerName $server -Name $Services -ErrorAction SilentlyContinue | Stop-Service -Force -ErrorAction SilentlyContinue -WarningAction $warningActionValue\n        }\n        else {\n            Get-Service -ComputerName $server -Name $Services -ErrorAction SilentlyContinue | ForEach-Object {\n                $service = Get-CimInstance -ClassName \"win32_service\" -Filter \"Name = '$($_.Name)'\"\n\n                Stop-Process -Id \"$($service.ProcessId)\" -Force -ErrorAction SilentlyContinue -WarningAction $warningActionValue\n            }\n        }\n    }\n\n    $Results = foreach ($server in $ComputerName) {\n        Write-PSFMessage -Level Verbose -Message \"Working against: $server - listing services\"\n        Get-Service -ComputerName $server -Name $Services -ErrorAction SilentlyContinue | Select-Object @{Name = \"Server\"; Expression = { $Server } }, Name, Status, StartType, DisplayName\n    }\n    \n    Write-PSFMessage -Level Verbose \"Results are: $Results\" -Target ($Results.Name -join \",\")\n    \n    $Results | Select-PSFObject -TypeName \"D365FO.TOOLS.Environment.Service\" Server, DisplayName, Status, StartType, Name\n}"
  },
  {
    "path": "d365fo.tools/functions/stop-d365eventtrace.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Stop an Event Trace session\n        \n    .DESCRIPTION\n        Stop an Event Trace session that you have started earlier with the d365fo.tools\n        \n    .PARAMETER SessionName\n        Name of the tracing session that you want to stop\n        \n        Default value is \"d365fo.tools.trace\"\n        \n    .EXAMPLE\n        PS C:\\> Stop-D365EventTrace\n        \n        This will stop an Event Trace session.\n        It will use the \"d365fo.tools.trace\" as the SessionName parameter.\n        \n    .NOTES\n        Tags: ETL, EventTracing, EventTrace\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        This cmdlet/function was inspired by the work of Michael Stashwick (@D365Stuff)\n        \n        He blog is located here: https://www.d365stuff.co/\n        \n        and the blogpost that pointed us in the right direction is located here: https://www.d365stuff.co/trace-batch-jobs-and-more-via-cmd-logman/\n#>\n\nfunction Stop-D365EventTrace {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [string] $SessionName = \"d365fo.tools.trace\"\n    )\n\n    end {\n        Write-PSFMessage -Level Verbose -Message \"Stopping the trace\" -Target $SessionName\n        \n        Stop-Trace -SessionName $SessionName -ETS\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/switch-d365activedatabase.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Switches the 2 databases. The Old wil be renamed _original\n        \n    .DESCRIPTION\n        Switches the 2 databases. The Old wil be renamed _original\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER SourceDatabaseName\n        The database that takes the DatabaseName's place\n        \n    .PARAMETER DestinationSuffix\n        The suffix that you want to append onto the database that is being switched out (DestinationDatabaseName / DatabaseName)\n        \n        The default value is \"_original\" to mimic the official guides from Microsoft\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Switch-D365ActiveDatabase -SourceDatabaseName \"GoldenConfig\"\n        \n        This will switch the default database AXDB out and put \"GoldenConfig\" in its place instead.\n        It will use the default value for DestinationSuffix which is \"_original\".\n        The destination database \"AXDB\" will be renamed to \"AXDB_original\".\n        The GoldenConfig database will be renamed to \"AXDB\".\n        \n    .EXAMPLE\n        PS C:\\> Switch-D365ActiveDatabase -SourceDatabaseName \"AXDB_original\" -DestinationSuffix \"_reverted\"\n        \n        This will switch the default database AXDB out and put \"AXDB_original\" in its place instead.\n        It will use the \"_reverted\" value for DestinationSuffix parameter.\n        The destination database \"AXDB\" will be renamed to \"AXDB_reverted\".\n        The \"AXDB_original\" database will be renamed to \"AXDB\".\n        \n        This is used when you did a switch already and need to switch back to the original database.\n        \n        This example assumes that the used the first example to switch in the GoldenConfig database with default parameters.\n        \n    .NOTES\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        Author: Rasmus Andersen (@ITRasmus)\n        \n#>\nfunction Switch-D365ActiveDatabase {\n    [CmdletBinding()]\n    param (\n        [string] $DatabaseServer = $Script:DatabaseServer,\n\n        [Alias('DestinationDatabaseName')]\n        [string] $DatabaseName = $Script:DatabaseName,\n\n        [string] $SqlUser = $Script:DatabaseUserName,\n\n        [string] $SqlPwd = $Script:DatabaseUserPassword,\n        \n        [Parameter(Mandatory = $true)]\n        [Alias('NewDatabaseName')]\n        [string] $SourceDatabaseName,\n\n        [string] $DestinationSuffix = \"_original\",\n\n        [switch] $EnableException\n    )\n\n    $dbToBeName = \"$DatabaseName$DestinationSuffix\"\n\n    $SqlParamsToBe = @{ DatabaseServer = $DatabaseServer; DatabaseName = \"master\";\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd\n    }\n    \n    $dbName = Get-D365Database -Name \"$dbToBeName\" @SqlParamsToBe\n\n    if (-not($null -eq $dbName)) {\n        $messageString = \"There <c='em'>already exists</c> a database named: <c='em'>`\"$dbToBeName`\"</c> on the server. You need to run the <c='em'>Remove-D365Database</c> cmdlet to remove the already existing database. Re-run this cmdlet once the other database has been removed.\"\n        Write-PSFMessage -Level Host -Message $messageString -Target $dbToBeName\n        Stop-PSFFunction -Message \"Stopping because database already exists on the server.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', '')))\n        return\n    }\n\n    $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n    $SqlParamsSource = @{ DatabaseServer = $DatabaseServer; DatabaseName = $SourceDatabaseName;\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd\n    }\n\n    $SqlCommand = Get-SqlCommand @SqlParamsSource -TrustedConnection $UseTrustedConnection\n\n    $SqlCommand.CommandText = \"SELECT COUNT(1) FROM dbo.USERINFO WHERE ID = 'Admin'\"\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n        Write-PSFMessage -Level Verbose -Message \"Testing the new database for being a valid AXDB database.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n        $null = $sqlCommand.ExecuteScalar()\n    }\n    catch {\n        $messageString = \"It seems that the new database either <c='em'>doesn't exists</c>, isn't a <c='em'>valid</c> AxDB database or your don't have enough <c='em'>permissions</c>.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand)\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n    }\n    \n    $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = \"master\";\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd\n    }\n\n    $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n\n    if ($DatabaseServer -like \"*database.windows.net\") {\n        $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\switch-database-tier2.sql\") -join [Environment]::NewLine\n    }\n    else {\n        $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\switch-database-tier1.sql\") -join [Environment]::NewLine\n    }\n    \n    $sqlCommand.CommandText = $commandText\n\n    $null = $sqlCommand.Parameters.AddWithValue(\"@DestinationName\", $DatabaseName)\n    $null = $sqlCommand.Parameters.AddWithValue(\"@SourceName\", $SourceDatabaseName)\n    $null = $sqlCommand.Parameters.AddWithValue(\"@ToBeName\", $dbToBeName)\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n        Write-PSFMessage -Level Verbose -Message \"Switching out the $DatabaseName database with: $SourceDatabaseName.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n\n        $null = $sqlCommand.ExecuteNonQuery()\n    }\n    catch {\n        $messageString = \"Something went wrong while <c='em'>switching</c> out the AXDB database.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand)\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n        \n        $sqlCommand.Dispose()\n    }\n    \n    [PSCustomObject]@{\n        OldDatabaseNewName = \"$dbToBeName\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/test-d365command.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Validate or show parameter set details with colored output\n        \n    .DESCRIPTION\n        Analyze a function and it's parameters\n        \n        The cmdlet / function is capable of validating a string input with function name and parameters\n        \n    .PARAMETER CommandText\n        The string that you want to analyze\n        \n        If there is parameter value present, you have to use the opposite quote strategy to encapsulate the string correctly\n        \n        E.g. for double quotes\n        -CommandText 'Import-D365Bacpac -ImportModeTier2 -SqlUser \"sqladmin\" -SqlPwd \"XyzXyz\" -BacpacFile2 \"C:\\temp\\uat.bacpac\"'\n        \n        E.g. for single quotes\n        -CommandText \"Import-D365Bacpac -ExportModeTier2 -SqlUser 'sqladmin' -SqlPwd 'XyzXyz' -BacpacFile2 'C:\\temp\\uat.bacpac'\"\n        \n    .PARAMETER Mode\n        The operation mode of the cmdlet / function\n        \n        Valid options are:\n        - Validate\n        - ShowParameters\n        \n    .PARAMETER SplatInput\n        Pass in your hashtable that you use for your command execution and have it validated\n        \n    .PARAMETER ShowSplatStyleV1\n        Include an hashtable splatting for all parameter sets in the output\n        \n        The example is built like this:\n        PS C:\\> $params = @{}\n        PS C:\\> $params.PropertyName = \"SAMPLEVALUE\"\n        PS C:\\> Test-FakeCommand @params\n        \n        \n    .PARAMETER ShowSplatStyleV2\n        Include an hashtable splatting for all parameter sets in the output\n        \n        The example is built like this:\n        PS C:\\> $params = @{\n        PS C:\\> PropertyName = \"SAMPLEVALUE\"\n        PS C:\\> }\n        PS C:\\> Test-FakeCommand @params\n        \n    .PARAMETER IncludeHelp\n        Switch to instruct the cmdlet / function to output a simple guide with the colors in it\n        \n    .EXAMPLE\n        PS C:\\> Test-D365Command -CommandText 'Import-D365Bacpac -ImportModeTier2 -SqlUser \"sqladmin\" -SqlPwd \"XyzXyz\" -BacpacFile2 \"C:\\temp\\uat.bacpac\"' -Mode \"Validate\" -IncludeHelp\n        \n        This will validate all the parameters that have been passed to the Import-D365Bacpac cmdlet.\n        All supplied parameters that matches a parameter will be marked with an asterisk.\n        Will print the coloring help.\n        \n    .EXAMPLE\n        PS C:\\> Test-D365Command -CommandText 'Import-D365Bacpac' -Mode \"ShowParameters\" -IncludeHelp\n        \n        This will display all the parameter sets and their individual parameters.\n        Will print the coloring help.\n        \n    .EXAMPLE\n        PS C:\\> $params = @{}\n        PS C:\\> $params.DatabaseName = \"SAMPLEVALUE\"\n        PS C:\\> Test-D365Command -CommandText 'Import-D365Bacpac -ImportModeTier2' -SplatInput $params -Mode \"Validate\"\n        \n        This builds a hashtable with a property names \"DatabaseName\".\n        The hashtable is passed to the cmdlet to be part of the validation.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Test-D365Command {\n    [CmdletBinding()]\n    \n    param (\n        [Parameter(Mandatory = $true, Position = 1)]\n        [string] $CommandText,\n\n        [Parameter(Mandatory = $true, Position = 2)]\n        [ValidateSet('Validate', 'ShowParameters')]\n        [string] $Mode,\n\n        [hashtable] $SplatInput,\n\n        [switch] $ShowSplatStyleV1,\n\n        [switch] $ShowSplatStyleV2,\n\n        [switch] $IncludeHelp\n    )\n\n    $commonParameters = 'Verbose', 'Debug', 'ErrorAction', 'WarningAction', 'InformationAction', 'ErrorVariable', 'WarningVariable', 'InformationVariable', 'OutVariable', 'OutBuffer', 'PipelineVariable', 'Confirm', 'WhatIf'\n    \n    $colorParmsNotFound = \"Red\"\n    $colorCommandName = \"Green\"\n    $colorMandatoryParam = \"Yellow\"\n    $colorNonMandatoryParam = \"DarkGray\"\n    $colorFoundAsterisk = \"Green\"\n    $colorNotFoundAsterisk = \"Magenta\"\n    $colParmValue = \"DarkCyan\"\n    $colorEqualSign = \"DarkGray\"\n    $colorVariable = \"Green\"\n    $colorProperty = \"White\"\n    $colorCommandNameSplat = \"Yellow\"\n    $colorComment = \"DarkGreen\"\n\n    if(-not ($null -eq $SplatInput)) {\n        $CommandText = \"$CommandText \"+ $(($SplatInput.Keys | ForEach-Object {\"-$($_) `\"$($SplatInput.Item($_))`\"\"}) -Join \" \" )\n    }\n\n    #Match to find the command name: Non-Whitespace until the first whitespace\n    $commandMatch = ($CommandText | Select-String '\\S+\\s*').Matches\n\n    if ($null -eq $commandMatch) {\n        Write-PSFMessage -Level Host -Message \"The function was unable to extract a valid command name from the supplied command text. Please try again.\"\n        Stop-PSFFunction -Message \"Stopping because of missing command name.\"\n        return\n    }\n\n    $commandName = $commandMatch.Value.Trim()\n\n    $res = Get-Command $commandName -ErrorAction Ignore\n\n    if ($null -eq $res) {\n        Write-PSFMessage -Level Host -Message \"The function was unable to get the help of the command. Make sure that the command name is valid and try again.\"\n        Stop-PSFFunction -Message \"Stopping because command name didn't return any help.\"\n        return\n    }\n\n    $sbHelp = New-Object System.Text.StringBuilder\n    $sbParmsNotFound = New-Object System.Text.StringBuilder\n    $sbSplatStyleV1 = New-Object System.Text.StringBuilder\n    $sbSplatStyleV2 = New-Object System.Text.StringBuilder\n\n    switch ($Mode) {\n        \"Validate\" {\n            #Match to find the parameters: Whitespace Dash Non-Whitespace\n            $inputParameterMatch = ($CommandText | Select-String '\\s{1}[-]\\S+' -AllMatches).Matches\n                    \n            if (-not ($null -eq $inputParameterMatch)) {\n                $inputParameterNames = $inputParameterMatch.Value.Trim(\"-\", \" \")\n                Write-PSFMessage -Level Verbose -Message \"All input parameters - $($inputParameterNames -join \",\")\" -Target ($inputParameterNames -join \",\")\n            }\n            else {\n                Write-PSFMessage -Level Host -Message \"The function was unable to extract any parameters from the supplied command text. Please try again.\"\n                Stop-PSFFunction -Message \"Stopping because of missing input parameters.\"\n                return\n            }\n\n            $availableParameterNames = (Get-Command $commandName).Parameters.keys | Where-Object {$commonParameters -NotContains $_}\n            Write-PSFMessage -Level Verbose -Message \"Available parameters - $($availableParameterNames -join \",\")\" -Target ($availableParameterNames -join \",\")\n\n            $inputParameterNotFound = $inputParameterNames | Where-Object {$availableParameterNames -NotContains $_}\n\n            if ($inputParameterNotFound.Length -gt 0) {\n                $null = $sbParmsNotFound.AppendLine(\"Parameters that <c='em'>don't exists</c>\")\n                $inputParameterNotFound | ForEach-Object {\n                    $null = $sbParmsNotFound.AppendLine(\"<c='$colorParmsNotFound'>$($_)</c>\")\n                }\n            }\n\n            foreach ($parmSet in (Get-Command $commandName).ParameterSets) {\n                $null = $sb = New-Object System.Text.StringBuilder\n                $null = $sb.AppendLine(\"ParameterSet Name: <c='em'>$($parmSet.Name)</c> - Validated List\")\n                $null = $sb.Append(\"<c='$colorCommandName'>$commandName </c>\")\n\n                $parmSetParameters = $parmSet.Parameters | Where-Object name -NotIn $commonParameters\n        \n                foreach ($parameter in $parmSetParameters) {\n                    $parmFoundInCommandText = $parameter.Name -In $inputParameterNames\n                            \n                    $color = \"$colorNonMandatoryParam\"\n        \n                    if ($parameter.IsMandatory -eq $true) { $color = \"$colorMandatoryParam\" }\n        \n                    $null = $sb.Append(\"<c='$color'>-$($parameter.Name)</c>\")\n        \n                    if ($parmFoundInCommandText) {\n                        $null = $sb.Append(\"<c='$colorFoundAsterisk'>* </c>\")\n                    }\n                    elseif ($parameter.IsMandatory -eq $true) {\n                        $null = $sb.Append(\"<c='$colorNotFoundAsterisk'>* </c>\")\n                    }\n                    else {\n                        $null = $sb.Append(\" \")\n                    }\n        \n                    if (-not ($parameter.ParameterType -eq [System.Management.Automation.SwitchParameter])) {\n                        $null = $sb.Append(\"<c='$colParmValue'>PARAMVALUE </c>\")\n                    }\n                }\n        \n                $null = $sb.AppendLine(\"\")\n                Write-PSFHostColor -String \"$($sb.ToString())\"\n            }\n\n            $null = $sbHelp.AppendLine(\"\")\n            $null = $sbHelp.AppendLine(\"<c='$colorParmsNotFound'>$colorParmsNotFound</c> = Parameter not found\")\n            $null = $sbHelp.AppendLine(\"<c='$colorCommandName'>$colorCommandName</c> = Command Name\")\n            $null = $sbHelp.AppendLine(\"<c='$colorMandatoryParam'>$colorMandatoryParam</c> = Mandatory Parameter\")\n            $null = $sbHelp.AppendLine(\"<c='$colorNonMandatoryParam'>$colorNonMandatoryParam</c> = Optional Parameter\")\n            $null = $sbHelp.AppendLine(\"<c='$colParmValue'>$colParmValue</c> = Parameter value\")\n            $null = $sbHelp.AppendLine(\"<c='$colorFoundAsterisk'>*</c> = Parameter was filled\")\n            $null = $sbHelp.AppendLine(\"<c='$colorNotFoundAsterisk'>*</c> = Mandatory missing\")\n        }\n\n        \"ShowParameters\" {\n            foreach ($parmSet in (Get-Command $commandName).ParameterSets) {\n                $sb = New-Object System.Text.StringBuilder\n                $sbSplatStyleV1 = New-Object System.Text.StringBuilder\n                $sbSplatStyleV2 = New-Object System.Text.StringBuilder\n\n                $null = $sb.AppendLine(\"ParameterSet Name: <c='em'>$($parmSet.Name)</c> - Parameter List\")\n                $null = $sb.Append(\"<c='$colorCommandName'>$commandName </c>\")\n                \n                $null = $sbSplatStyleV1.AppendLine(\"<c='$colorComment'>#Hashtable splatting style V1 - ParameterSet Name: </c><c='em'>$($parmSet.Name)</c>\").AppendLine(\"<c='$colorVariable'>`$params</c> <c='$colorEqualSign'>=</c> <c='$colorProperty'>@{}</c>\")\n                $null = $sbSplatStyleV2.AppendLine(\"<c='$colorComment'>#Hashtable splatting style V2 - ParameterSet Name: </c><c='em'>$($parmSet.Name)</c>\").AppendLine(\"<c='$colorVariable'>`$params</c> <c='$colorEqualSign'>=</c> <c='$colorProperty'>@{</c>\")\n\n                $parmSetParameters = $parmSet.Parameters | Where-Object name -NotIn $commonParameters\n        \n                foreach ($parameter in $parmSetParameters) {\n                    $color = \"$colorNonMandatoryParam\"\n                    $mandatoryComment = $null\n\n                    if ($parameter.IsMandatory -eq $true) {\n                        $color = \"$colorMandatoryParam\"\n\n                        $mandatoryComment = \"   <c='$color'>#MANDATORY</c>\"\n                    }\n\n                    $null = $sbSplatStyleV1.AppendLine(\"<c='$colorVariable'>`$params</c><c='$colorProperty'>.$($parameter.Name)</c> <c='$colorEqualSign'>=</c> <c='$colParmValue'>`\"SAMPLEVALUE`\"</c>$mandatoryComment\")\n                    $null = $sbSplatStyleV2.AppendLine(\"<c='$colorProperty'>$($parameter.Name)</c> <c='$colorEqualSign'>=</c> <c='$colParmValue'>`\"SAMPLEVALUE`\"</c>$mandatoryComment\")\n        \n                    $null = $sb.Append(\"<c='$color'>-$($parameter.Name) </c>\")\n        \n                    if (-not ($parameter.ParameterType -eq [System.Management.Automation.SwitchParameter])) {\n                        $null = $sb.Append(\"<c='$colParmValue'>PARAMVALUE </c>\")\n                    }\n                }\n        \n                $null = $sb.AppendLine(\"\")\n                $null = $sbSplatStyleV2.AppendLine(\"<c='$colorProperty'>}</c>\")\n                $null = $sbSplatStyleV1.AppendLine(\"<c='$colorCommandNameSplat'>$commandName</c> <c='$colorVariable'>@params</c>\")\n                $null = $sbSplatStyleV2.AppendLine(\"<c='$colorCommandNameSplat'>$commandName</c> <c='$colorVariable'>@params</c>\")\n\n                Write-PSFHostColor -String \"$($sb.ToString())\"\n                \n                if ($ShowSplatStyleV1) { Write-PSFHostColor -String \"$($sbSplatStyleV1.ToString())\" }\n                if ($ShowSplatStyleV2) { Write-PSFHostColor -String \"$($sbSplatStyleV2.ToString())\" }\n            }\n\n            $null = $sbHelp.AppendLine(\"\")\n            $null = $sbHelp.AppendLine(\"<c='$colorCommandName'>$colorCommandName</c> = Command Name\")\n            $null = $sbHelp.AppendLine(\"<c='$colorMandatoryParam'>$colorMandatoryParam</c> = Mandatory Parameter\")\n            $null = $sbHelp.AppendLine(\"<c='$colorNonMandatoryParam'>$colorNonMandatoryParam</c> = Optional Parameter\")\n            $null = $sbHelp.AppendLine(\"<c='$colParmValue'>$colParmValue</c> = Parameter value\")\n        }\n        Default {}\n    }\n\n    if ($sbParmsNotFound.ToString().Trim().Length -gt 0) {\n        Write-PSFHostColor -String \"$($sbParmsNotFound.ToString())\"\n    }\n \n    if ($IncludeHelp) {\n        Write-PSFHostColor -String \"$($sbHelp.ToString())\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/test-d365dataverseconnection.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Test the dataverse connection\n        \n    .DESCRIPTION\n        Invokes the built-in http communication endpount, that validates the connection between the D365FO environment and dataverse\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .EXAMPLE\n        PS C:\\> Test-D365DataverseConnection\n        \n        This will invoke the http communication component, that validates the basic settings between D365FO and Dataverse.\n        It will output the raw details from the call, to make it easier to troubleshoot the connectivity between D365FO and Dataverse.\n        \n    .NOTES\n        General notes\n#>\nfunction Test-D365DataverseConnection {\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param (\n        [string] $BinDir = \"$Script:BinDir\\bin\"\n    )\n\n    begin {\n    }\n\n    process {\n        $cdsApiPath = \"sdkmessages\";\n        $httpCommunicationDllPath = Join-Path -Path $BinDir -ChildPath \"Microsoft.Dynamics.HttpCommunication.dll\"\n        \n        if (-not (Test-PathExists -Path $httpCommunicationDllPath -Type Leaf)) {\n            return\n        }\n\n        Write-PSFMessage -Level Verbose -Message \"Loading the 'Microsoft.Dynamics.HttpCommunication.dll' file into the current session.\"\n        Add-Type -Path $httpCommunicationDllPath\n\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Building the logger object, to handle the output from the test.\"\n            $assembly = [System.Reflection.Assembly]::LoadFile($httpCommunicationDllPath)\n            $loggerType = $assembly.GetType(\"Microsoft.Dynamics.HttpCommunication.Logging.InMemoryLogger\")\n            $bindingFlags = [System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::Public\n            $loggerConstructor = $loggerType.GetConstructor($bindingFlags, $null, [System.Type]::EmptyTypes, $null)\n            $logger = $loggerConstructor.Invoke($null)\n\n            Write-PSFMessage -Level Verbose -Message \"Building the client/request object, to execute the test / validation.\"\n            $cdsWebApiClient = New-Object Microsoft.Dynamics.HttpCommunication.Cds.CdsWebApiClient $logger;\n            $bindingFlags = [System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic\n            $method = [Microsoft.Dynamics.HttpCommunication.Cds.CdsWebApiClient].GetMethod(\"GetWithStringResponse\", $bindingFlags, $null, @([string]), $null)\n            \n            Write-PSFMessage -Level Verbose -Message \"Invoking the test / validation request.\"\n            $task = $method.Invoke($cdsWebApiClient, @($cdsApiPath))\n            $response = $task.GetAwaiter().GetResult()\n\n            $response\n        }\n        catch {\n            Write-PSFHostColor -String $logger.LogContent.ToString() -DefaultColor Red\n\n            if ($logger.LogContent.ToString() -like '*Cannot Find Thumbprint by Certificatename*') {\n                Write-PSFMessage -Level Host -Message \"The <c='em'>'Cannot Find Thumbprint by Certificatename'</c> indicates that you need to run the <c='em'>'New-D365EntraIntegration'</c> cmdlet.\"\n                Write-PSFMessage -Level Host -Message \"You should read the following links: <c='em'>https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/dev-tools/secure-developer-vm#external-integrations</c> and <c='em'>https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/business-events/che-be-ve-error</c>.\"\n                Stop-PSFFunction -Message \"Stopping because the 'Cannot Find Thumbprint by Certificatename' error was encounted\"\n                return\n            }\n            elseif ($logger.LogContent.ToString() -like '*Expected aud https://securityservice.operations365.dynamics.com*') {\n                Write-PSFMessage -Level Host -Message \"The <c='em'>'Expected aud https://securityservice.operations365.dynamics.com'</c> indicates that you need to configure Azure Entra (Registered Application) between your <c='em'>D365FO</c> environment and the connected <c='em'>Dataverse</c> environment.\"\n                Write-PSFMessage -Level Host -Message \"You should read the following link: <c='em'>https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/business-events/che-be-ve-error</c>.\"\n                Stop-PSFFunction -Message \"Stopping because the 'Cannot Find Thumbprint by Certificatename' error was encounted\"\n                return\n            }\n        }\n    }\n\n    end {\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/test-d365entraintegration.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Test the Entra Id integration\n        \n    .DESCRIPTION\n        Validates the configuration of the web.config file and the certificate for the environment\n        \n        If any of the configuration is missing or in someway incorrect, it will prompt and stating corrective actions needed\n        \n    .EXAMPLE\n        PS C:\\> Test-D365EntraIntegration\n        \n        This will validate the settings inside the web.config file.\n        It will search for Aad.Realm, Infrastructure.S2SCertThumbprint, GraphApi.GraphAPIServicePrincipalCert\n        It will search for the certificate that matches the thumbprint.\n        \n        A result set example:\n        \n        EntraAppId                           Thumbprint                               Subject    Expiration\n        ----------                           ----------                               -------    ----------\n        e068e004-8bec-48c3-a36f-2ab4982ee738 0768175DF3DFDEA3FA78925ADC1E588707649335 CN=CHEAuth 2/5/2026 8:09:28 AM\n        \n    .NOTES\n        Based on: https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/dev-tools/secure-developer-vm#external-integrations\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Test-D365EntraIntegration {\n    param (\n    )\n\n    if (-not ($Script:IsAdminRuntime)) {\n        Write-PSFMessage -Level Critical -Message \"It seems that you ran this cmdlet <c='em'>non-elevated</c>. Testing the Entra integration requires you to run this cmdlet from an elevated console. Please exit the current console and start a new with `\"Run As Administrator`\"\"\n        Stop-PSFFunction -Message \"Stopping because the function is not run elevated\"\n        return\n    }\n\n    # Check web.config\n    $webConfigFile = Join-Path -Path $Script:AOSPath $Script:WebConfig\n    \n    if (-not (Test-PathExists -Path $webConfigFile -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue)) {\n        Write-PSFMessage -Level Host -Message \"Unable to find the web.config file.\"\n        Stop-PSFFunction -Message \"Stopping because the web.config file could not be found\"\n    }\n    \n    $config = @{}\n\n    [xml]$xml = Get-Content $webConfigFile\n    $nodes = ($xml.configuration.appSettings).ChildNodes\n\n    $config.AadRealm = $nodes | Where-Object -Property Key -eq \"Aad.Realm\" | Select-Object -First 1 -ExpandProperty value\n    $config.S2SCertThumbprint = $nodes | Where-Object -Property Key -eq \"Infrastructure.S2SCertThumbprint\" | Select-Object -First 1 -ExpandProperty value\n    $config.GraphAPIServicePrincipalCert = $nodes | Where-Object -Property Key -eq \"GraphApi.GraphAPIServicePrincipalCert\" | Select-Object -First 1 -ExpandProperty value\n    \n    if ([System.String]::IsNullOrWhiteSpace($config.AadRealm)) {\n        Write-PSFMessage -Level Host -Message \"The <c='em'>'Aad.Realm'</c> value is empty. This indicates that you need to run the <c='em'>'New-D365EntraIntegration'</c> cmdlet.\"\n        Stop-PSFFunction -Message \"Stopping because the 'Aad.Realm' value is empty\"\n    }\n    \n    if ([System.String]::IsNullOrWhiteSpace($config.S2SCertThumbprint)) {\n        Write-PSFMessage -Level Host -Message \"The <c='em'>'Infrastructure.S2SCertThumbprint'</c> value is empty. This indicates that you need to run the <c='em'>'New-D365EntraIntegration'</c> cmdlet.\"\n        Stop-PSFFunction -Message \"Stopping because the 'Infrastructure.S2SCertThumbprint' value is empty\"\n    }\n\n    if ([System.String]::IsNullOrWhiteSpace($config.GraphAPIServicePrincipalCert)) {\n        Write-PSFMessage -Level Host -Message \"The <c='em'>'GraphApi.GraphAPIServicePrincipalCert'</c> value is empty. This indicates that you need to run the <c='em'>'New-D365EntraIntegration'</c> cmdlet.\"\n        Stop-PSFFunction -Message \"Stopping because the 'GraphApi.GraphAPIServicePrincipalCert' value is empty\"\n    }\n\n    if ((-not [System.String]::IsNullOrWhiteSpace($config.S2SCertThumbprint)) -and $config.S2SCertThumbprint -ne $config.GraphAPIServicePrincipalCert) {\n        Write-PSFMessage -Level Host -Message \"The <c='em'>'Infrastructure.S2SCertThumbprint'</c> and the <c='em'>'GraphApi.GraphAPIServicePrincipalCert'</c> value do not match each other. This indicates that you have a <c='em'>corrupted</c> configuration. Running the <c='em'>'New-D365EntraIntegration'</c> cmdlet could assist with fixing the configuration.\"\n        Stop-PSFFunction -Message \"Stopping because the 'Infrastructure.S2SCertThumbprint' and 'GraphApi.GraphAPIServicePrincipalCert' values do not match\"\n    }\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    # Check wif.config\n    $wifConfigFile = Join-Path -Path $Script:AOSPath $Script:WifConfig\n    \n    if (-not (Test-PathExists -Path $wifConfigFile -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue)) {\n        Write-PSFMessage -Level Host -Message \"Unable to find the wif.config file.\"\n        Stop-PSFFunction -Message \"Stopping because the wif.config file could not be found\"\n    }\n    \n    [xml]$xml = Get-Content $wifConfigFile\n    $nodes = ($xml.'system.identityModel'.identityConfiguration.securityTokenHandlers.securityTokenHandlerConfiguration.audienceUris).ChildNodes\n    $config.AudienceUri = $nodes | Where-Object { $_.value -like \"*$($config.AadRealm)*\" } | Select-Object -First 1 -ExpandProperty value\n\n    if ([System.String]::IsNullOrWhiteSpace($config.AudienceUri)) {\n        Write-PSFMessage -Level Host -Message \"The <c='em'>'AudienceUri'</c> value is empty.  This indicates that you have a <c='em'>corrupted</c> configuration. Try running the <c='em'>'New-D365EntraIntegration'</c> cmdlet to fix the configuration.\"\n        Stop-PSFFunction -Message \"Stopping because the 'AudienceUri' value is empty\"\n    }\n    elseif ($config.AadRealm -ne $config.AudienceUri) {\n        Write-PSFMessage -Level Host -Message \"The <c='em'>'Aad.Realm'</c> and the <c='em'>'AudienceUri'</c> value do not match each other. This indicates that you have a <c='em'>corrupted</c> configuration. Try running the <c='em'>'New-D365EntraIntegration'</c> cmdlet to fix the configuration.\"\n        Stop-PSFFunction -Message \"Stopping because the 'Aad.Realm' and 'AudienceUri' values do not match\"\n    }\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    # Check certificate\n    $certStoreLocation = \"Cert:\\LocalMachine\\My\"\n    \n    $certEntra = Get-ChildItem -Path $certStoreLocation -ErrorAction SilentlyContinue | Where-Object { $_.Thumbprint -eq $config.S2SCertThumbprint } | Select-Object -First 1\n    \n    if ($null -eq $certEntra) {\n        Write-PSFMessage -Level Host -Message \"Unable to find any certificate in the certificate store <c='em'>'$certStoreLocation'</c> that matches the thumbprint <c='em'>'$($config.S2SCertThumbprint)'</c>.\"\n        Stop-PSFFunction -Message \"Stopping because no certificate matching the thumbprint was found\"\n        return\n    }\n\n    [PSCustomObject][ordered]@{\n        EntraAppId = $config.AadRealm.replace(\"spn:\", \"\")\n        Thumbprint = $config.S2SCertThumbprint\n        Subject    = $certEntra.Subject\n        Expiration = $certEntra.NotAfter\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/test-d365flightservicecatalogid.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Test if the FlightingServiceCatalogID is present and filled out\n        \n    .DESCRIPTION\n        Test if the FlightingServiceCatalogID element exists in the web.config file used by D365FO\n        \n    .PARAMETER AosServiceWebRootPath\n        Path to the root folder where to locate the web.config file\n        \n    .EXAMPLE\n        PS C:\\> Test-D365FlightServiceCatalogId\n        \n        This will open the web.config and check if the FlightingServiceCatalogID element is present or not.\n        \n    .NOTES\n        Tags: Flight, Flighting\n        \n        Author: Mötz Jensen (@Splaxi))\n        \n        The DataAccess.FlightingServiceCatalogID must already be set in the web.config file.\n        https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages#features-flighted-in-data-management-and-enabling-flighted-features\n#>\n\nfunction Test-D365FlightServiceCatalogId {\n    [CmdletBinding()]\n    param (\n        [string]$AosServiceWebRootPath = $Script:AOSPath\n    )\n\n    $res = @{}\n\n    try {\n        $WebConfigFile = Join-Path -Path $AosServiceWebRootPath -ChildPath $Script:WebConfig\n        \n        Write-PSFMessage -Level Verbose -Message \"Retrieve the FlightingServiceCatalogID\" -Target $WebConfigFile\n\n        $FlightServiceNode = Select-Xml -XPath \"/configuration/appSettings/add[@key='DataAccess.FlightingServiceCatalogID']/@value\" -Path $WebConfigFile\n        \n        if($null -eq $FlightServiceNode){\n            Write-PSFMessage -Level Host -Message \"The <c='em'>DataAccess.FlightingServiceCatalogID</c> child element under the <c='em'>AppSettings</c> element is missing. See <c='em'>https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages#features-flighted-in-data-management-and-enabling-flighted-features</c> for details.\"\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n\n        $res.FlightingServiceCatalogID = $FlightServiceNode.Node.Value\n        \n        Write-PSFMessage -Level Verbose -Message \"FlightingServiceCatalogID: $FlightServiceId\" -Target $WebConfigFile\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while reading from the web.config file\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n\n    if(-not [System.String]::IsNullOrEmpty($res.FlightingServiceCatalogID)){\n        [PsCustomObject]$res\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/test-d365labelidisvalid.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Checks if a string is a valid 'Label Id' format\n        \n    .DESCRIPTION\n        This function will validate if a string is a valid 'Label Id' format.\n        \n    .PARAMETER LabelId\n        The LabelId string thay you want to validate\n        \n    .EXAMPLE\n        PS C:> Test-D365LabelIdIsValid -LabelId \"ABC123\"\n        \n        This will test the if the LabelId is valid.\n        It will use the \"ABC123\" as the LabelId parameter.\n        \n        The expected result is $true\n        \n    .EXAMPLE\n        PS C:> Test-D365LabelIdIsValid -LabelId \"@ABC123\"\n        \n        This will test the if the LabelId is valid.\n        It will use the \"@ABC123\" as the LabelId parameter.\n        \n        The expected result is $true\n        \n    .EXAMPLE\n        PS C:> Test-D365LabelIdIsValid -LabelId \"@ABC123_1\"\n        \n        This will test the if the LabelId is valid.\n        It will use the \"@ABC123_1\" as the LabelId parameter.\n        \n        The expected result is $false\n        \n    .EXAMPLE\n        PS C:> Test-D365LabelIdIsValid -LabelId \"ABC.123\" #False\n        \n        This will test the if the LabelId is valid.\n        It will use the \"ABC.123\" as the LabelId parameter.\n        \n        The expected result is $false\n        \n    .NOTES\n        Author: Alex Kwitny (@AlexOnDAX)\n        \n        The intent of this function is to be used with other methods to create valid labels via scripting.\n        \n#>\nfunction Test-D365LabelIdIsValid {\n    [CmdletBinding()]\n    [OutputType([bool])]\n    param\n    (\n        [Parameter(Mandatory = $True)]\n        [string] $LabelId\n    )\n    \n    $RegexOptions = [System.Text.RegularExpressions.RegexOptions]::IgnoreCase -bor [System.Text.RegularExpressions.RegexOptions]::Compiled -bor [System.Text.RegularExpressions.RegexOptions]::CultureInvariant\n\n    $Matcher_New_LabelID = New-Object System.Text.RegularExpressions.Regex('(^[a-zA-Z_])([a-zA-Z\\d_])*$', $RegexOptions)\n    $Matcher_Legacy_LabelID = New-Object System.Text.RegularExpressions.Regex([System.String]::Format([System.IFormatProvider][System.Globalization.CultureInfo]::InvariantCulture, \"^{0}{1}{2}$\", [System.Object]'@', [System.Object]\"[a-zA-Z]\\w\\w\", [System.Object]\"\\d+\"), $RegexOptions)\n    $Matcher_New_Label_WithLabelFile = New-Object System.Text.RegularExpressions.Regex(\"(?<AtSign>\\@)(?<LabelFileId>[a-zA-Z]\\w*):(?<LabelId>[a-zA-Z]\\w*)\", $RegexOptions)\n\n    if (!$LabelId) {\n        $false\n        return\n    }\n\n    if (!($Matcher_New_LabelID.IsMatch($LabelId)) -and !($Matcher_Legacy_LabelID.IsMatch($LabelId))) {\n        $Matcher_New_Label_WithLabelFile.IsMatch($LabelId)\n        return\n    }\n\n    $true\n}"
  },
  {
    "path": "d365fo.tools/functions/update-d365bacpacmodelfilesingletable.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Update the \"model.xml\" from the bacpac file to a single table\n        \n    .DESCRIPTION\n        Update the \"model.xml\" file from inside the bacpac file to only handle a single table\n        \n        This can be used to restore a single table as fast as possible to a new data\n        \n        The table will be created like ordinary bacpac restore, expect it will only have the raw table definition and indexes, all other objects are dropped\n        \n        The output can be used directly with the Import-D365Bacpac cmdlet and its ModelFile parameter, see the example sections for more details\n        \n    .PARAMETER Path\n        Path to the bacpac file that you want to work against\n        \n        It can also be a zip file\n        \n    .PARAMETER Table\n        Name of the table that you want to be kept inside the model file when the update is done\n        \n    .PARAMETER Schema\n        Schema where the table that you want to work against exists\n        \n        The default value is \"dbo\"\n        \n    .PARAMETER OutputPath\n        Path to where you want the updated bacpac model file to be saved\n        \n        Default value is: \"c:\\temp\\d365fo.tools\"\n        \n    .PARAMETER Force\n        Switch to instruct the cmdlet to overwrite the bacpac model file specified in the OutputPath\n        \n    .EXAMPLE\n        PS C:\\> Update-D365BacpacModelFileSingleTable -Path \"c:\\temp\\d365fo.tools\\bacpac.model.xml\" -Table \"SalesTable\"\n        \n        This will create an updated bacpac.model.xml file with only the SalesTable to be imported.\n        It will read the \"c:\\temp\\d365fo.tools\\bacpac.model.xml\" file.\n        It will use the default \"dbo\" as the Schema parameter.\n        It will use the \"SalesTable\" as the Table parameter.\n        It will use the \"c:\\temp\\d365fo.tools\\dbo.salestable.model.xml\" as the default path for OutputPath parameter.\n        \n    .EXAMPLE\n        PS C:\\> Update-D365BacpacModelFileSingleTable -Path \"c:\\temp\\d365fo.tools\\bacpac.model.xml\" -Table \"CommissionSalesGroup\" -Schema \"AX\"\n        \n        This will create an updated bacpac.model.xml file with only the \"CommissionSalesGroup\", from the \"AX\" schema, to be imported.\n        It will read the \"c:\\temp\\d365fo.tools\\bacpac.model.xml\" file.\n        It will use the \"AX\" as the Schema for the table.\n        It will use the \"CommissionSalesGroup\" as the Table parameter.\n        It will use the \"c:\\temp\\d365fo.tools\\ax.CommissionSalesGroup.model.xml\" as the default path for OutputPath parameter.\n        \n    .EXAMPLE\n        PS C:\\> Update-D365BacpacModelFileSingleTable -Path \"c:\\temp\\d365fo.tools\\bacpac.model.xml\" -Table \"SalesTable\" -OutputPath \"c:\\temp\\troubleshoot.xml\"\n        \n        This will create an updated bacpac.model.xml file with only the SalesTable to be imported.\n        It will read the \"c:\\temp\\d365fo.tools\\bacpac.model.xml\" file.\n        It will use the default \"dbo\" as the Schema parameter.\n        It will use the \"SalesTable\" as the Table parameter.\n        It will use the \"c:\\temp\\troubleshoot.xml\" as the path for OutputPath parameter.\n        \n    .EXAMPLE\n        PS C:\\> Export-D365BacpacModelFile -Path \"c:\\Temp\\AxDB.bacpac\" | Update-D365BacpacModelFileSingleTable -Table SalesTable\n        \n        This will create an updated bacpac.model.xml file with only the SalesTable to be imported.\n        It will read the bacpac model file generated from the Export-D365BacpacModelFile cmdlet.\n        It will use the default \"dbo\" as the Schema parameter.\n        It will use the \"SalesTable\" as the Table parameter.\n        It will use the \"c:\\temp\\d365fo.tools\\dbo.salestable.model.xml\" as the default path for OutputPath parameter.\n        \n    .EXAMPLE\n        PS C:\\> Update-D365BacpacModelFileSingleTable -Path \"c:\\temp\\d365fo.tools\\bacpac.model.xml\" -Table \"SalesTable\" -Force\n        \n        This will create an updated bacpac.model.xml file with only the SalesTable to be imported.\n        It will read the \"c:\\temp\\d365fo.tools\\bacpac.model.xml\" file.\n        It will use the default \"dbo\" as the Schema parameter.\n        It will use the \"SalesTable\" as the Table parameter.\n        It will use the \"c:\\temp\\d365fo.tools\\dbo.salestable.model.xml\" as the default path for OutputPath parameter.\n        \n        It will overwrite the \"c:\\temp\\d365fo.tools\\dbo.salestable.model.xml\" if it already exists.\n        \n    .NOTES\n        Tags: Bacpac, Servicing, Data, SqlPackage, Import, Table, Troubleshooting\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Update-D365BacpacModelFileSingleTable {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]\n        [Alias('ModelFile')]\n        [Alias('File')]\n        [string] $Path,\n\n        [Parameter(Mandatory = $true)]\n        [string] $Table,\n\n        [string] $Schema = \"dbo\",\n\n        [string] $OutputPath = $Script:DefaultTempPath,\n\n        [switch] $Force\n    )\n    \n    begin {\n        Invoke-TimeSignal -Start\n\n        if ([System.IO.File]::GetAttributes($OutputPath).HasFlag([System.IO.FileAttributes]::Directory)) {\n            $OutputPath = Join-Path -Path $OutputPath -ChildPath \"$Schema.$Table.model.xml\"\n        }\n        \n        if (-not $Force) {\n            if ((-not (Test-PathExists -Path $OutputPath -Type Leaf -ShouldNotExist -ErrorAction SilentlyContinue -WarningAction SilentlyContinue))) {\n                Write-PSFMessage -Level Host -Message \"The <c='em'>$OutputPath</c> already exists. Consider changing the <c='em'>OutputPath</c> path or set the <c='em'>Force</c> parameter to overwrite the file.\"\n                return\n            }\n        }\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        if ($Schema -NotLike \"[*]\") {\n            $Schema = \"[$Schema]\"\n        }\n        \n        if ($Table -NotLike \"[*]\") {\n            $Table = \"[$Table]\"\n        }\n    }\n\n    process {\n        if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n        if (Test-PSFFunctionInterrupt) { return }\n        \n        $xmlFile = [System.Xml.XmlReader]::Create($Path)\n\n        $settings = [System.Xml.XmlWriterSettings]::new()\n        $settings.Indent = $true\n        $settings.Encoding = [System.Text.UTF8Encoding]::new($false)\n        $outFile = [System.Xml.XmlWriter]::Create($OutputPath, $settings)\n\n        while ($xmlFile.Read()) {\n\n            if ($xmlFile.NodeType -in \"XmlDeclaration\", \"ProcessingInstruction\") {\n                $outFile.WriteProcessingInstruction($xmlFile.Name, $xmlFile.Value)\n            }\n            elseif ($xmlFile.NodeType -eq \"Element\" -and $xmlFile.Name -eq \"DataSchemaModel\") {\n                $outFile.WriteStartElement($xmlFile.name, \"http://schemas.microsoft.com/sqlserver/dac/Serialization/2012/02\")\n                if ($xmlFile.HasAttributes) {\n                    while ($xmlFile.MoveToNextAttribute()) {\n                        if ($xmlFile.name -ne \"xmlns\") {\n                            $outFile.WriteAttributeString($xmlFile.Name, $xmlFile.Value)\n                        }\n                    }\n                }\n            }\n            elseif ($xmlFile.NodeType -eq \"Element\" -and $xmlFile.Name -eq \"Model\") {\n                $outFile.WriteStartElement($xmlFile.name)\n            }\n            elseif ($xmlFile.NodeType -eq \"Element\" -and $xmlFile.Depth -eq 2) {\n                $rawElement = $($xmlFile.ReadOuterXml() -replace 'xmlns=\".*\"', '')\n                \n                if (-not $($rawElement -match 'Type=\"(?<Type>.*?)\".*?>')) {\n                    continue\n                }\n\n                if ($Matches.Type -NotIn \"SqlSchema\", \"SqlTable\", \"SqlDatabaseOptions\", \"SqlGenericDatabaseScopedConfigurationOptions\", \"SqlIndex\", \"SqlPrimaryKeyConstraint\") {\n                    continue\n                }\n        \n                if ($Matches.Type -eq \"SqlSchema\") {\n                    if (-not $($rawElement -match 'Name=\"(?<Name>.*?)\".*?>')) {\n                        continue\n                    }\n        \n                    if ($Matches.Name -ne $Schema) {\n                        continue\n                    }\n\n                    Write-PSFMessage -Level Verbose -Message \"SqlSchema found\" -Target $rawElement\n                }\n\n                if ($Matches.Type -eq \"SqlTable\") {\n                    if (-not $($rawElement -match 'Name=\"(?<Name>.*?)\".*?>')) {\n                        continue\n                    }\n                    \n                    if ($Matches.Name -ne \"$Schema.$Table\") {\n                        continue\n                    }\n        \n                    Write-PSFMessage -Level Verbose -Message \"SqlTable found\" -Target $rawElement\n\n                    $rawElement = $rawElement -replace \"\\s*.*<AttachedAnnotation Disambiguator=`\".*`\".*/>\", \"\"\n                }\n                \n                if ($Matches.Type -eq \"SqlIndex\") {\n                    if (-not $($rawElement -match 'Name=\"(?<Name>.*?)\".*?>')) {\n                        continue\n                    }\n                    \n                    if (-not $Matches.Name.StartsWith(\"$Schema.$Table\", [System.StringComparison]::InvariantCultureIgnoreCase)) {\n                        continue\n                    }\n\n                    Write-PSFMessage -Level Verbose -Message \"SqlIndex found\" -Target $rawElement\n                }\n\n                if ($Matches.Type -eq \"SqlPrimaryKeyConstraint\") {\n                    if (-not $(([System.Xml.XmlDocument]$rawElement).SelectSingleNode(\"//Relationship[@Name='DefiningTable']/Entry/References/@Name\").\"#text\").Equals(\"$Schema.$Table\", [System.StringComparison]::InvariantCultureIgnoreCase)) {\n                        continue\n                    }\n\n                    Write-PSFMessage -Level Verbose -Message \"SqlPrimaryKeyConstraint found\" -Target $rawElement\n                }\n                \n                $outFile.WriteRaw($rawElement)\n            }\n            else {\n                if ($xmlFile.NodeType -eq \"EndElement\" -and $xmlFile.Name -in \"Model\", \"DataSchemaModel\") {\n                    $outFile.WriteEndElement()\n                }\n            }\n        }\n\n        [PSCustomObject]@{\n            File     = $OutputPath\n            Filename = $(Split-Path -Path $OutputPath -Leaf)\n        }\n    }\n    \n    end {\n        if ($outFile) {\n            $outFile.Flush()\n            $outFile.Close()\n            $outFile.Dispose()\n        }\n\n        if ($xmlFile) {\n            $xmlFile.Close()\n            $xmlFile.Dispose()\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/functions/update-d365user.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Updates the user details in the database\n        \n    .DESCRIPTION\n        Is capable of updating all the user details inside the UserInfo table to enable a user to sign in\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER Email\n        The search string to select which user(s) should be updated.\n        \n        The parameter supports wildcards. E.g. -Email \"*@contoso.com*\"\n        \n    .PARAMETER Company\n        The company the user should start in.\n        \n    .EXAMPLE\n        PS C:\\> Update-D365User -Email \"claire@contoso.com\"\n        \n        This will search for the user with the e-mail address claire@contoso.com and update it with needed information based on the tenant owner of the environment\n        \n    .EXAMPLE\n        PS C:\\> Update-D365User -Email \"*contoso.com\"\n        \n        This will search for all users with an e-mail address containing 'contoso.com' and update them with needed information based on the tenant owner of the environment\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Update-D365User {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [string]$DatabaseServer = $Script:DatabaseServer,\n\n        [string]$DatabaseName = $Script:DatabaseName,\n\n        [string]$SqlUser = $Script:DatabaseUserName,\n\n        [string]$SqlPwd = $Script:DatabaseUserPassword,\n\n        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]\n        [string]$Email,\n\n        [string]$Company\n\n    )\n    begin {\n        Invoke-TimeSignal -Start\n        \n        $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n\n        $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n            SqlUser = $SqlUser; SqlPwd = $SqlPwd\n        }\n\n        $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n        \n        $sqlCommand_Update = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection\n\n        try {\n            $sqlCommand.Connection.Open()\n\n            $sqlCommand_Update.Connection.Open()\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n    }\n\n    process {\n        $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\get-user.sql\") -join [Environment]::NewLine\n\n        $null = $sqlCommand.Parameters.Add(\"@Email\", $Email.Replace(\"*\", \"%\"))\n\n        $sqlCommand_Update.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\update-user.sql\") -join [Environment]::NewLine\n\n        try {\n            Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n        \n            $reader = $sqlCommand.ExecuteReader()\n\n            while ($reader.Read() -eq $true) {\n                Write-PSFMessage -Level Verbose -Message \"Building the update statement with the needed details.\"\n\n                $userId = \"$($reader.GetString($($reader.GetOrdinal(\"ID\"))))\"\n                $networkAlias = \"$($reader.GetString($($reader.GetOrdinal(\"NETWORKALIAS\"))))\"\n\n                $userAuth = Get-D365UserAuthenticationDetail $networkAlias\n\n                $null = $sqlCommand_Update.Parameters.AddWithValue(\"@id\", $userId)\n                $null = $sqlCommand_Update.Parameters.AddWithValue(\"@networkDomain\", $userAuth[\"NetworkDomain\"])\n                $null = $sqlCommand_Update.Parameters.AddWithValue(\"@sid\", $userAuth[\"SID\"])\n                $null = $sqlCommand_Update.Parameters.AddWithValue(\"@identityProvider\", $userAuth[\"IdentityProvider\"])\n\n                $null = $sqlCommand_Update.Parameters.AddWithValue(\"@Company\", $Company)\n\n                Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $sqlCommand_Update)\n\n                $null = $sqlCommand_Update.ExecuteNonQuery()\n\n                $sqlCommand_Update.Parameters.Clear()\n            }\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n        finally {\n            $reader.close()\n            $sqlCommand.Parameters.Clear()\n        }\n    }\n    \n    end {\n        if ($sqlCommand_Update.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand_Update.Connection.Close()\n        }\n\n        $sqlCommand_Update.Dispose()\n    \n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/configurations/configuration.ps1",
    "content": "﻿<#\nThis is an example configuration file\n\nBy default, it is enough to have a single one of them,\nhowever if you have enough configuration settings to justify having multiple copies of it,\nfeel totally free to split them into multiple files.\n#>\n\n<#\n# Example Configuration\nSet-PSFConfig -Module 'd365fo.tools' -Name 'Example.Setting' -Value 10 -Initialize -Validation 'integer' -Handler { } -Description \"Example configuration setting. Your module can then use the setting using 'Get-PSFConfigValue'\"\n#>\n\nSet-PSFConfig -Module 'd365fo.tools' -Name 'Import.DoDotSource' -Value $false -Initialize -Validation 'bool' -Description \"Whether the module files should be dotsourced on import. By default, the files of this module are read as string value and invoked, which is faster but worse on debugging.\"\nSet-PSFConfig -Module 'd365fo.tools' -Name 'Import.IndividualFiles' -Value $false -Initialize -Validation 'bool' -Description \"Whether the module files should be imported individually. During the module build, all module code is compiled into few files, which are imported instead by default. Loading the compiled versions is faster, using the individual files is easier for debugging and testing out adjustments.\"\n\nSet-PSFConfig -FullName \"d365fo.tools.workstation.mode\" -Value $false -Initialize -Description \"Setting to assist the module to grab the URL from configuration rather from the non existing dll files.\"\n\nSet-PSFConfig -FullName \"d365fo.tools.azure.storage.accounts\" -Value @{} -Initialize -Description \"Object that stores different Azure Storage Account and their details.\"\nSet-PSFConfig -FullName \"d365fo.tools.active.azure.storage.account\" -Value @{} -Initialize -Description \"Object that stores the Azure Storage Account details that should be used during the module.\"\nSet-PSFConfig -FullName \"d365fo.tools.active.logic.app\" -Value @{} -Initialize -Description \"Object that stores the Azure Logic App details that should be used during the module.\"\n\nSet-PSFConfig -FullName \"d365fo.tools.lcs.projectid\" -Value \"\" -Initialize -Description \"Project number for the specific LCS project that you want to upload to.\"\nSet-PSFConfig -FullName \"d365fo.tools.lcs.clientid\" -Value \"\" -Initialize -Description \"Client Id of the Azure Registered App that you configured to be able to use the API of LCS.\"\nSet-PSFConfig -FullName \"d365fo.tools.lcs.lcsapiuri\" -Value \"\" -Initialize -Description \"URI / URL for the LCS API.\"\nSet-PSFConfig -FullName \"d365fo.tools.lcs.activetokenexpireson\" -Value \"\" -Initialize -Description \"The time when the currently stored bearer token will expire. Measured in seconds from 1970-01-01 (UnixTime).\"\nSet-PSFConfig -FullName \"d365fo.tools.lcs.bearertoken\" -Value \"\" -Initialize -Description \"The bearer token used to authenticate / authorize against LCS when you want to upload files.\"\nSet-PSFConfig -FullName \"d365fo.tools.lcs.refreshtoken\" -Value \"\" -Initialize -Description \"The refresh token, that can be used to obtain a new bearer token from Azure Active Directory.\"\n\nSet-PSFConfig -FullName \"d365fo.tools.active.broadcast.message.config.name\" -Value \"\" -Initialize -Description \"Name of the broadcast message configuration that should be the default / active configuration for the module.\"\n\nSet-PSFConfig -FullName \"d365fo.tools.path.sqlpackage\" -Value \"C:\\Program Files (x86)\\Microsoft SQL Server\\140\\DAC\\bin\\SqlPackage.exe\" -Initialize -Description \"Path to the default location where SqlPackage.exe is located.\"\n\nSet-PSFConfig -FullName \"d365fo.tools.azure.common.oauth.token\" -Value \"https://login.microsoftonline.com/common/oauth2/token\" -Initialize -Description \"URI / URL for the Azure Active Directory OAuth 2.0 endpoint for tokens\"\n\nSet-PSFConfig -FullName \"d365fo.tools.path.rsat\" -Value \"C:\\Program Files (x86)\\Regression Suite Automation Tool\" -Initialize -Description \"Path to the default location where RSAT is located.\"\n\nSet-PSFConfig -FullName \"d365fo.tools.path.rsatplayback\" -Value \"C:\\Users\\$($env:UserName)\\AppData\\Roaming\\regressionTool\\playback\" -Initialize -Description \"Path to the playback output location where RSAT is writing all the output values.\"\n\nSet-PSFConfig -FullName \"d365fo.tools.path.azcopy\" -Value \"C:\\temp\\d365fo.tools\\AzCopy\\AzCopy.exe\" -Initialize -Description \"Path to the default location where AzCopy.exe is located.\"\n\nSet-PSFConfig -FullName \"d365fo.tools.path.nuget\" -Value \"C:\\temp\\d365fo.tools\\nuget\\nuget.exe\" -Initialize -Description \"Path to the default location where nuget.exe is located.\"\n"
  },
  {
    "path": "d365fo.tools/internal/configurations/readme.md",
    "content": "﻿# Configurations\n\nThrough the `PSFramework` you have a simple method that allows you to ...\n\n - Publish settings\n - With onboard documentation\n - Input validation\n - Scripts that run on change of settings\n - That can be discovered and updated by the user\n - That can be administrated by policy & DSC\n\nThe configuration system is a bit too complex to describe in a help file, you can however visit us at http://psframework.org for detailed guidance.\n\nAn example can be seen in the attached ps1 file"
  },
  {
    "path": "d365fo.tools/internal/functions/add-aadusersecurity.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Assign D365 Security configuration\n        \n    .DESCRIPTION\n        Assign the same security configuration as the ADMIN user in the D365FO database\n        \n    .PARAMETER sqlCommand\n        The SQL Command object that should be used when assigning the permissions\n        \n    .PARAMETER Id\n        Id of the user inside the D365FO database\n        \n    .EXAMPLE\n        PS C:\\> $SqlParams = @{\n        DatabaseServer = \"localhost\"\n        DatabaseName = \"AXDB\"\n        SqlUser = \"sqladmin\"\n        SqlPwd = \"Pass@word1\"\n        TrustedConnection = $false\n        }\n        \n        PS C:\\> $SqlCommand = Get-SqlCommand @SqlParams\n        PS C:\\> Add-AadUserSecurity -SqlCommand $SqlCommand -Id \"TestUser\"\n        \n        This will create a new Sql Command object using the Get-SqlCommand cmdlet and the $SqlParams hashtable containing all the needed parameters.\n        With the $SqlCommand in place it calls the Add-AadUserSecurity cmdlet and instructs it to update the \"TestUser\" to have the same security configuration as the ADMIN user.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Add-AadUserSecurity {\n    [OutputType('System.Boolean')]\n    param (\n        [Parameter(Mandatory = $true)]\n        [System.Data.SqlClient.SqlCommand] $SqlCommand,\n\n        [Parameter(Mandatory = $true)]\n        [string] $Id\n    )\n\n    $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\Set-AadUserSecurityInD365FO.sql\") -join [Environment]::NewLine\n   \n    $sqlCommand.CommandText = $commandText\n\n    $null = $sqlCommand.Parameters.Add(\"@Id\", $Id)\n\n    Write-PSFMessage -Level Verbose -Message \"Setting security roles in D365FO database\"\n\n    Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n    $differenceBetweenNewUserAndAdmin = $sqlCommand.ExecuteScalar()\n    \n    Write-PSFMessage -Level Verbose -Message \"Difference between new user and admin security roles $differenceBetweenNewUserAndAdmin\" -Target $differenceBetweenNewUserAndAdmin\n    \n    $SqlCommand.Parameters.Clear()\n\n    $differenceBetweenNewUserAndAdmin -eq 0\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/add-filetopackage.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Add a file to an archive (zipped) file\n        \n    .DESCRIPTION\n        Add the specified file to the specified archive (zipped) file in the specified path.\n        \n    .PARAMETER File\n        Path to the file that you want to add to the archive\n        \n    .PARAMETER Archive\n        Path to the archive (zipped) file where the file should be added\n        \n    .PARAMETER Path\n        Path where the file should be added to the archive. Default is the root of the archive.\n        \n    .PARAMETER OutputPath\n        Path where you want the modified archive to be stored. Default is the same path as the archive.\n        \n    .PARAMETER ClearPath\n        If the path already exists in the archive, it will be cleared before adding the file. Default is false.\n        \n    .EXAMPLE\n        PS C:\\> Add-FileToPackage -File C:\\Temp\\MyFile.txt -Archive C:\\Temp\\MyPackage.zip -Path \"AOSService\\Scripts\"\n        \n        This will take the \"C:\\Temp\\MyFile.txt\" file and add it to the C:\\Temp\\MyPackage.zip archive in the \"AOSService\\Scripts\" folder.\n        It will extract the \"C:\\Temp\\MyPackage.zip\" and add the \"C:\\Temp\\MyFile.txt\" in the \"AOSService\\Scripts\" folder of the extracted archive.\n        It will then compress (zip) the folder created by the extraction back into an archive file, overwriting the previous archive file.\n        \n    .NOTES\n        Author: Mötz Jensen (@splaxi)\n        Author: Szabolcs Eötvös\n        Author: Florian Hopfner (@FH-Inway)\n        \n#>\nfunction Add-FileToPackage {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 1 )]\n        [string] $File,\n\n        [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 2 )]\n        [string] $Archive,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 3 )]\n        [string] $Path = \"\",\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 4 )]\n        [string] $OutputPath = $Archive,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default')]\n        [Switch] $ClearPath\n    )\n\n    begin {\n    }\n\n    process {\n        if (-not (Test-PathExists -Path $File, $Archive -Type \"Leaf\")) { return }\n\n        $null = New-Item -Path (Split-Path $OutputPath -Parent) -ItemType Directory -ErrorAction SilentlyContinue\n\n        Unblock-File $File\n        Unblock-File $Archive\n\n        $ExtractionPath = [System.IO.Path]::GetTempPath()\n\n        $packageTemp = Join-Path $ExtractionPath ((Get-Random -Maximum 99999).ToString())\n\n        Write-PSFMessage -Level Verbose -Message \"Extracting the archive zip file to $packageTemp.\" -Target $packageTemp\n        Expand-Archive -Path $Archive -DestinationPath $packageTemp\n\n        $mergePath = Join-Path $packageTemp $Path\n\n        if (Test-Path -Path $mergePath) {\n            if ($ClearPath) {\n                Get-ChildItem -Path $mergePath | Remove-Item -Force -ErrorAction SilentlyContinue\n            }\n        }\n        else {\n            $null = New-Item -Path $mergePath -ItemType Directory -ErrorAction SilentlyContinue\n        }\n\n        Write-PSFMessage -Level Verbose -Message \"Copying the file into place.\"\n        Copy-Item -Path $File -Destination $mergePath\n\n        Write-PSFMessage -Level Verbose -Message \"Compressing the folder into a zip file and storing it at $OutputPath\" -Target $OutputPath\n        Compress-Archive -Path \"$packageTemp\\*\" -DestinationPath $OutputPath -Force\n\n        [PSCustomObject]@{\n            File = $OutputPath\n        }\n    }\n\n    end {\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/backup-file.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Backup a file\n        \n    .DESCRIPTION\n        Backup a file either in the same directory as the original file with a suffix or in a different directory.\n        \n    .PARAMETER File\n        Path to the file that you want to backup\n        \n    .PARAMETER Suffix\n        The suffix value that you want to append to the file name when backing it up in the same directory.\n        \n    .PARAMETER DestinationPath\n        Path to the folder where you want the backup file to be placed. This parameter is used when you want to backup the file in a different directory.\n        \n    .PARAMETER Force\n        Instructs the cmdlet to overwrite an already existing backup of the file.\n        \n    .EXAMPLE\n        PS C:\\> Backup-File -File c:\\temp\\d365fo.tools\\test.txt -Suffix \"Original\"\n        \n        This will backup the \"test.txt\" file as \"test_Original.txt\" inside \"c:\\temp\\d365fo.tools\\\"\n        \n    .EXAMPLE\n        PS C:\\> Backup-File -File c:\\temp\\d365fo.tools\\test.txt -Suffix \"Original\" -Force\n        \n        This will backup the \"test.txt\" file as \"test_Original.txt\" inside \"c:\\temp\\d365fo.tools\\\"\n        If the file already exists in the destination folder, it will be overwritten.\n        \n    .EXAMPLE\n        PS C:\\> Backup-File -File c:\\temp\\d365fo.tools\\test.txt -DestinationPath c:\\temp\\d365fo.tools\\backup\n        \n        This will backup the \"test.txt\" file to \"c:\\temp\\d365fo.tools\\backup\\test.txt\"\n        \n    .EXAMPLE\n        PS C:\\> Backup-File -File c:\\temp\\d365fo.tools\\test.txt -DestinationPath c:\\temp\\d365fo.tools\\backup -Force\n        \n        This will backup the \"test.txt\" file to \"c:\\temp\\d365fo.tools\\backup\\test.txt\"\n        If the file already exists in the destination folder, it will be overwritten.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        Author: Florian Hopfner (@FH-Inway)\n        \n#>\nfunction Backup-File {\n    [CmdletBinding(\n        DefaultParameterSetName = \"SameFolderWithSuffix\")]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $File,\n        \n        [Parameter(Mandatory = $true, ParameterSetName = \"SameFolderWithSuffix\")]\n        [string] $Suffix,\n\n        [Parameter(Mandatory = $true, ParameterSetName = \"DifferentFolder\")]\n        [string] $DestinationPath,\n\n        [switch] $Force\n    )\n\n    begin {\n        if (-not (Test-PathExists -Path $File -Type Leaf)) { return }\n    }\n\n    process {\n        if ($PSCmdlet.ParameterSetName -eq \"SameFolderWithSuffix\") {\n            $FileBackup = Get-BackupName -File $File -Suffix $Suffix\n        }\n        elseif ($PSCmdlet.ParameterSetName -eq \"DifferentFolder\") {\n            $FileName = Split-Path -Path $File -Leaf\n            $FileBackup = Join-Path -Path $DestinationPath -ChildPath $FileName\n        }\n\n        Write-PSFMessage -Level Verbose -Message \"Backing up $File to $FileBackup\" -Target (@($File, $FileBackup))\n\n        if (-not $Force) {\n            if (Test-PathExists -Path $FileBackup -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) {\n                Write-PSFMessage -Level Host -Message \"The <c='em'>$FileBackup</c> already exists. Consider changing the <c='em'>destination</c> path or set the <c='em'>Force</c> parameter to overwrite the file.\"\n                return\n            }\n        }\n\n        Copy-Item -Path $File -Destination $FileBackup -Force:$Force -PassThru | Select-PSFObject \"Name as Filename\", \"LastWriteTime as LastModified\", \"Fullname as File\"\n    }\n    \n}"
  },
  {
    "path": "d365fo.tools/internal/functions/complete-lcsuploadv2.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Complete the upload action in LCS\n        \n    .DESCRIPTION\n        Signal to LCS that the upload of the blob has completed\n        \n    .PARAMETER Token\n        The token to be used for the http request against the LCS API\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER AssetId\n        The unique id of the asset / file that you are trying to upload to LCS\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Complete-LcsUploadV2 -Token \"Bearer JldjfafLJdfjlfsalfd...\" -ProjectId 123456789 -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will commit the upload process for the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" in the LCS project with Id 123456789.\n        The http request will be using the \"Bearer JldjfafLJdfjlfsalfd...\" token for authentication against the LCS API.\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .NOTES\n        Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Complete-LcsUploadV2 {\n    [CmdletBinding()]\n    [OutputType()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [string]$Token,\n\n        [Parameter(Mandatory = $true)]\n        [int]$ProjectId,\n\n        [Parameter(Mandatory = $true)]\n        [string]$AssetId,\n\n        [Parameter(Mandatory = $false)]\n        [string]$LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n    \n    begin {\n        Invoke-TimeSignal -Start\n        \n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"POST\"\n        $parms.Uri = \"$LcsApiUri/box/fileasset/CommitFileAsset/$($ProjectId)?assetId=$AssetId\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n    }\n\n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in starting a new database refresh in LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception -Target $_\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/convert-hashtoargstringswitch.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Convert HashTable into an array\n        \n    .DESCRIPTION\n        Convert HashTable with switches inside into an array of Key:Value\n        \n    .PARAMETER InputObject\n        The HashTable object that you want to work against\n        \n        Shold only contain Key / Vaule, where value is $true or $false\n        \n    .PARAMETER KeyPrefix\n        The prefix that you want to append to the key of the HashTable\n        \n        The default value is \"-\"\n        \n    .PARAMETER ValuePrefix\n        The prefix that you want to append to the value of the HashTable\n        \n        The default value is \":\"\n        \n    .PARAMETER KeepCase\n        Instruct the cmdlet to keep the naming case of the properties from the hashtable\n        \n        Default value is: $true\n        \n    .EXAMPLE\n        PS C:\\> $params = @{NoPrompt = $true; CreateParents = $false}\n        PS C:\\> $arguments = Convert-HashToArgStringSwitch -Inputs $params\n        \n        This will convert the $params into an array of strings, each with the \"-Key:Value\" pattern.\n        \n    .EXAMPLE\n        PS C:\\> $params = @{NoPrompt = $true; CreateParents = $false}\n        PS C:\\> $arguments = Convert-HashToArgStringSwitch -InputObject $params -KeyPrefix \"&\" -ValuePrefix \"=\"\n        \n        This will convert the $params into an array of strings, each with the \"&Key=Value\" pattern.\n        \n    .NOTES\n        Tags: HashTable, Arguments\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Convert-HashToArgStringSwitch {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidDefaultValueSwitchParameter\", \"\")]\n    [CmdletBinding()]\n    [OutputType([System.String])]\n    param (\n        [HashTable] $InputObject,\n\n        [string] $KeyPrefix = \"-\",\n\n        [string] $ValuePrefix = \":\",\n\n        [switch] $KeepCase = $true\n    )\n\n    foreach ($key in $InputObject.Keys) {\n        $value = \"{0}\" -f $InputObject.Item($key).ToString()\n        if (-not $KeepCase) {$value = $value.ToLower()}\n        \"$KeyPrefix$($key)$ValuePrefix$($value)\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/convertto-booleanordefault.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Convert an object to boolean\n        \n    .DESCRIPTION\n        Convert an object to boolean or default it to the specified boolean value\n        \n    .PARAMETER Object\n        Input object that you want to work against\n        \n    .PARAMETER Default\n        The default boolean value you want returned if the convert / cast fails\n        \n    .EXAMPLE\n        PS C:\\> ConvertTo-BooleanOrDefault -Object \"1\" -Default $true\n        \n        This will try and convert the \"1\" value to a boolean value.\n        If the convert would fail, it would return the default value $true.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction ConvertTo-BooleanOrDefault {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingEmptyCatchBlock', '')]\n    [CmdletBinding()]\n    [OutputType('System.Boolean')]\n    param (\n        [Object] $Object,\n\n        [Boolean] $Default\n    )\n\n    [boolean] $result = $Default;\n    $stringTrue = @(\"yes\", \"true\", \"ok\", \"y\")\n\n    $stringFalse = @( \"no\", \"false\", \"n\")\n\n    try {\n        if (-not ($null -eq $Object) ) {\n            switch ($Object.ToString().ToLower()) {\n                {$stringTrue -contains $_} {\n                    $result = $true\n                    break\n                }\n                {$stringFalse -contains $_} {\n                    $result = $false\n                    break\n                }\n                default {\n                    $result = [System.Boolean]::Parser($Object.ToString())\n                    break\n                }\n            }\n        }\n    }\n    catch {\n    }\n\n    $result\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/convertto-hashtable.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Convert an object into a HashTable\n        \n    .DESCRIPTION\n        Convert an object into a HashTable, can be used with json objects to create a HashTable\n        \n    .PARAMETER InputObject\n        The object you want to convert\n        \n    .EXAMPLE\n        PS C:\\> $jsonString = '{\"Test1\":  \"Test1\",\"Test2\":  \"Test2\"}'\n        PS C:\\> $jsonString | ConvertFrom-Json | ConvertTo-Hashtable\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n        Original Author: Adam Bertram (@techsnips_io)\n        \n        Original blog post with the function explained:\n        https://4sysops.com/archives/convert-json-to-a-powershell-hash-table/\n        \n#>\n\nfunction ConvertTo-Hashtable {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCmdletCorrectly', '')]\n    [CmdletBinding()]\n    param (\n        [Parameter(ValueFromPipeline)]\n        $InputObject\n    )\n\n    process {\n        ## Return null if the input is null. This can happen when calling the function\n        ## recursively and a property is null\n        if ($null -eq $InputObject) {\n            return $null\n        }\n\n        ## Check if the input is an array or collection. If so, we also need to convert\n        ## those types into hash tables as well. This function will convert all child\n        ## objects into hash tables (if applicable)\n        if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string]) {\n            $collection = @(\n                foreach ($object in $InputObject) {\n                    ConvertTo-Hashtable -InputObject $object\n                }\n            )\n\n            ## Return the array but don't enumerate it because the object may be pretty complex\n            Write-Output -NoEnumerate $collection\n        }\n        elseif ($InputObject -is [psobject]) {\n            ## If the object has properties that need enumeration\n            ## Convert it to its own hash table and return it\n            $hash = @{}\n            foreach ($property in $InputObject.PSObject.Properties) {\n                $hash[$property.Name] = ConvertTo-Hashtable -InputObject $property.Value\n            }\n            $hash\n        }\n        else {\n            ## If the object isn't an array, collection, or other object, it's already a hash table\n            ## So just return it.\n            $InputObject\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/convertto-pscustomobject.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Convert a Hashtable into a PSCustomObject\n        \n    .DESCRIPTION\n        Convert a Hashtable into a PSCustomObject\n        \n    .PARAMETER InputObject\n        The hashtable you want to convert\n        \n    .EXAMPLE\n        PS C:\\> $params = @{SqlUser = \"\"; SqlPwd = \"\"}\n        PS C:\\> $params | ConvertTo-PsCustomObject\n        \n        This will create a hashtable with 2 properties.\n        It will convert the hashtable into a PSCustomObject\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n        Original blog post with the function explained:\n        https://blogs.msdn.microsoft.com/timid/2013/03/05/converting-pscustomobject-tofrom-hashtables/\n#>\n\nfunction ConvertTo-PsCustomObject {\n    [OutputType('[PsCustomObject]')]\n    param (\n        [Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]\n        [object[]] $InputObject\n    )\n    \n    begin { $i = 0 }\n    \n    process {\n        foreach ($myHashtable in $InputObject) {\n            if ($myHashtable.GetType().Name -eq 'hashtable') {\n                $output = New-Object -TypeName PsObject\n                Add-Member -InputObject $output -MemberType ScriptMethod -Name AddNote -Value {\n                    Add-Member -InputObject $this -MemberType NoteProperty -Name $args[0] -Value $args[1]\n                }\n\n                $myHashtable.Keys | Sort-Object | ForEach-Object {\n                    $output.AddNote($_, $myHashtable.$_)\n                }\n\n                $output\n            }\n            elseif ($myHashtable.GetType().Name -eq 'OrderedDictionary') {\n                $output = New-Object -TypeName PsObject\n                Add-Member -InputObject $output -MemberType ScriptMethod -Name AddNote -Value {\n                    Add-Member -InputObject $this -MemberType NoteProperty -Name $args[0] -Value $args[1]\n                }\n\n                $myHashtable.Keys | ForEach-Object {\n                    $output.AddNote($_, $myHashtable.$_)\n                }\n\n                $output\n            }\n            else {\n                Write-PSFMessage -Level Warning -Message \"Index `$i is not of type [hashtable]\" -Target $i\n            }\n\n            $i += 1\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/copy-filetolcsblob.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Copy local file to Azure Blob Storage\n        \n    .DESCRIPTION\n        Copy local file to Azure Blob Storage that is used by LCS\n        \n    .PARAMETER FilePath\n        Path to the file you want to upload to the Azure Blob storage\n        \n    .PARAMETER FullUri\n        The full URI, including SAS token and Policy Permissions to the blob\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Copy-FileToLcsBlob -FilePath \"C:\\temp\\d365fo.tools\\GOLDEN.bacpac\" -FullUri \"https://uswedpl1catalog.blob.core.windows.net/....\"\n        \n        This will upload the \"C:\\temp\\d365fo.tools\\GOLDEN.bacpac\" to the \"https://uswedpl1catalog.blob.core.windows.net/....\" Blob Storage location.\n        It is required that the FullUri contains all the needed SAS tokens and Policy Permissions for the upload to succeed.\n        \n    .NOTES\n        Tags: Azure Blob, LCS, Upload\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Copy-FileToLcsBlob {\n    [CmdletBinding()]\n    [OutputType()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [string]$FilePath,\n        \n        [Parameter(Mandatory = $true)]\n        [System.Uri]$FullUri,\n\n        [switch] $EnableException\n    )\n\n    Invoke-TimeSignal -Start\n\n    Write-PSFMessage -Level Verbose -Message \"Initializing the needed .net objects to work against Azure Blob.\" -Target $FullUri\n    $cloudblob = New-Object -TypeName Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob -ArgumentList @($FullUri)\n\n    try {\n        $uploadResult = Get-AsyncResult -Task $cloudblob.UploadFromFileAsync([System.String]$FilePath)\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while uploading the desired file to Azure Blob.\" -Exception $PSItem.Exception -Target $FullUri\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n \n    Invoke-TimeSignal -End\n    \n    $uploadResult\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-applicationenvironment.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Load all necessary information about the D365 instance\n        \n    .DESCRIPTION\n        Load all servicing dll files from the D365 instance into memory\n        \n    .EXAMPLE\n        PS C:\\> Get-ApplicationEnvironment\n        \n        This will load all the different dll files into memory.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-ApplicationEnvironment {\n    [System.Collections.ArrayList] $Files2Process = New-Object -TypeName \"System.Collections.ArrayList\"\n\n    $AOSPath = Join-Path $script:ServiceDrive \"\\AOSService\\webroot\\bin\"\n    \n    Write-PSFMessage -Level Verbose -Message \"Testing if we are running on a AOS server or not.\"\n    if (-not (Test-Path -Path $AOSPath -PathType Container)) {\n        Write-PSFMessage -Level Verbose -Message \"The machine is NOT an AOS server.\"\n        \n        $MRPath = Join-Path $script:ServiceDrive \"MRProcessService\\MRInstallDirectory\\Server\\Services\"\n        \n        Write-PSFMessage -Level Verbose -Message \"Testing if we are running on a BI / MR server or not.\"\n        if (-not (Test-Path -Path $MRPath -PathType Container)) {\n            Write-PSFMessage -Level Verbose -Message \"It seems that you ran this cmdlet on a machine that doesn't have the assemblies needed to obtain system details. Most likely you ran it on a <c='em'>personal workstation / personal computer</c>.\"\n            return\n        }\n        else {\n            Write-PSFMessage -Level Verbose -Message \"The machine is a BI / MR server.\"\n            $BasePath = $MRPath\n\n            $null = $Files2Process.Add((Join-Path $script:ServiceDrive \"Monitoring\\Instrumentation\\Microsoft.Dynamics.AX.Authentication.Instrumentation.dll\"))\n        }\n    }\n    else {\n        Write-PSFMessage -Level Verbose -Message \"The machine is an AOS server.\"\n        $BasePath = $AOSPath\n\n        $null = $Files2Process.Add((Join-Path $BasePath \"Microsoft.Dynamics.AX.Authentication.Instrumentation.dll\"))\n    }\n\n    Write-PSFMessage -Level Verbose -Message \"Shadow cloning all relevant assemblies to the Microsoft.Dynamics.ApplicationPlatform.Environment.dll to avoid locking issues. This enables us to install updates while having d365fo.tools loaded\"\n        \n    $null = $Files2Process.Add((Join-Path $BasePath \"Microsoft.Dynamics.AX.Configuration.Base.dll\"))\n    $null = $Files2Process.Add((Join-Path $BasePath \"Microsoft.Dynamics.BusinessPlatform.SharedTypes.dll\"))\n    $null = $Files2Process.Add((Join-Path $BasePath \"Microsoft.Dynamics.AX.Framework.EncryptionEngine.dll\"))\n    $null = $Files2Process.Add((Join-Path $BasePath \"Microsoft.Dynamics.AX.Security.Instrumentation.dll\"))\n    $null = $Files2Process.Add((Join-Path $BasePath \"Microsoft.Dynamics.ApplicationPlatform.Environment.dll\"))\n\n    Import-AssemblyFileIntoMemory -Path $($Files2Process.ToArray()) -UseTempFolder\n\n    if (Test-PSFFunctionInterrupt) { return }\n\n    Write-PSFMessage -Level Verbose -Message \"All assemblies loaded. Getting environment details.\"\n    $environment = [Microsoft.Dynamics.ApplicationPlatform.Environment.EnvironmentFactory]::GetApplicationEnvironment()\n    \n    $environment\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-asyncresult.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Simple abstraction to handle asynchronous executions\n        \n    .DESCRIPTION\n        Simple abstraction to handle asynchronous executions for several other cmdlets\n        \n    .PARAMETER Task\n        The task you want to work / wait for to complete\n        \n    .EXAMPLE\n        PS C:\\> $client = New-Object -TypeName System.Net.Http.HttpClient\n        PS C:\\> Get-AsyncResult -Task $client.SendAsync($request)\n        \n        This will take the client (http) and have it send a request using the asynchronous pattern.\n        \n    .NOTES\n        Tags: Async, Waiter, Wait\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Get-AsyncResult {\n    [CmdletBinding()]\n    [OutputType('Object')]\n    param (\n        [Parameter(Mandatory = $true, Position = 1)]\n        [object] $Task\n    )\n\n    Write-PSFMessage -Level Verbose -Message \"Building the Task Waiter and start waiting.\" -Target $Task\n    $Task.GetAwaiter().GetResult()\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-axaggregatedimensions.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get Aggregate Dimension\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all Aggregate Dimensions\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Get-AxAggregateDimensions\n        \n        This will get all objects.\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nFunction Get-AxAggregateDimensions {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    param(\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    BEGIN {\n        Import-GenerateReportAssemblies\n\n        $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n        $providerConfig.XppMetadataPath = $PackageDirectory\n        $providerConfig.MetadataPath = $PackageDirectory\n\n        $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig)\n    }\n\n    PROCESS {\n    \n        $aggregateDimensionsModelInfos = $metadataProvider.AggregateDimensions.GetPrimaryKeysWithModelInfo()\n        \n        foreach ($tuple in $aggregateDimensionsModelInfos) {\n            $elementName = $tuple.Item1\n\n            $element = $metadataProvider.AggregateDimensions.Read($elementName)\n\n            $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair\n                Name       = $element.Name\n                DataSource = $element.Table\n            }\n            \n            $outItems\n        }\n    }\n\n    END {}\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-axaggregatemeasures.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get Aggregate Measure\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all Aggregate Measures\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Get-AxAggregateMeasures\n        \n        This will get all objects.\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nFunction Get-AxAggregateMeasures {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    param(\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    BEGIN {\n        Import-GenerateReportAssemblies\n\n        $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n        $providerConfig.XppMetadataPath = $PackageDirectory\n        $providerConfig.MetadataPath = $PackageDirectory\n\n        $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig)\n        \n        $aggregateDimensions = Get-AxAggregateDimensions -BinDir $BinDir -PackageDirectory $PackageDirectory\n        $aggregateDimensionsHash = $aggregateDimensions | ArrayToHash\n    }\n\n    PROCESS {\n\n        $aggregateMeasurementsModelInfos = $metadataProvider.AggregateMeasurements.GetPrimaryKeysWithModelInfo()\n        \n        foreach ($tuple in $aggregateMeasurementsModelInfos) {\n            $elementName = $tuple.Item1\n\n            $element = $metadataProvider.AggregateMeasurements.Read($elementName)\n\n            foreach ($k in $element.MeasureGroups) {\n                $dimensionsArray = @()\n\n                #creates an array of dimensions and their data source in parenthesis per MeasureGroup\n                foreach ($i in $k.Dimensions) {\n                    $pos = $i.ToString().IndexOf(\" \")\n                    $i = $i.ToString().Substring(0, $pos)\n\n                    $dimensionsArray += ($i + \" (\" + $aggregateDimensionsHash[$i].DataSource + \")\")\n                }\n                \n                $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair\n                    Name                   = $element.Name\n                    MeasureGroup           = $k.Name\n                    MeasureGroupDataSource = $k.Table\n                    Measures               = [String]::join(\", \", $k.Measures)\n                    Dimensions             = [String]::join(\", \", $dimensionsArray)\n                }\n\n                $outItems\n            }\n        }\n    }\n}\n\nFunction ArrayToHash {\n    param()\n    begin { $hash = @{} }\n    process { $hash[$_.Name] = $_ }\n    end { return $hash }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-axdataentities.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get Data Entity\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all Data Entities and their fields\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Get-AxDataEntities\n        \n        This will get all objects.\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nFunction Get-AxDataEntities {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    param(\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    BEGIN {\n        Import-GenerateReportAssemblies\n\n        $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n        $providerConfig.XppMetadataPath = $PackageDirectory\n        $providerConfig.MetadataPath = $PackageDirectory\n\n        $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig)\n    }\n\n    PROCESS {\n\n        $dataEntityModelInfos = $metadataProvider.DataEntityViews.GetPrimaryKeysWithModelInfo()\n\n        foreach ($tuple in $dataEntityModelInfos) {\n            $elementName = $tuple.Item1\n\n            $element = $metadataProvider.DataEntityViews.Read($elementName)\n\n            #\n            # Build list of DataSources\n            #\n            $datasourceList = @()\n            foreach ($datasource in $element.ViewMetadata.DataSources) {\n                $datasourceList += New-Object PSObject -Property @{ # create a hash table of the name/value pair\n                    DataSourceName  = $datasource.Name\n                    DataSourceTable = $datasource.Table\n                }\n                $datasourceList += QueryDataSourceRecursion $datasource.DataSources\n            }\n\n            #\n            # Convert DataSource list to hash\n            #\n            $dataSourceHash = @{}\n            $datasourceList | ForEach-Object {\n                $dataSourceHash[$_.DataSourceName] = $_\n            }\n\n            foreach ($j in $element.Fields) {\n\n                #filter out system fields\n                if ($j -notlike \"AX_*\") {\n                    $typeName = $j.GetType().Name\n                    $field_binding = \"\"\n\n                    if ($typename -eq \"AxDataEntityViewMappedField\") {\n\n                        $tableName = \"\"\n                        if ($dataSourceHash.ContainsKey($j.DataSource)) {\n                            $tableName = $dataSourceHash[$j.DataSource].DataSourceTable\n                        }\n                        $field_binding = $j.DataSource + \"(\" + $tableName + \").\" + $j.DataField\n\n                    }\n                    elseif ($null -ne $j.IsComputedField -and $null -ne $j.ComputedFieldMethod) {\n\n                        # handle case of AxDataEntityViewUnmappedField{PrimitiveType}\n                        $field_binding = \"METHOD: \" + $j.ComputedFieldMethod\n\n                    }\n                    else {\n                        Write-PSFMessage -Level \"Warning\" -Message \"Unexpected type $typeName\"\n                    }\n\n                    $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair\n                        Name                  = $element.Name\n                        Public                = $element.IsPublic\n                        ODataAccessible       = $element.IsPublic\n                        PublicCollectionName  = $element.PublicCollectionName\n                        StagingTable          = $element.DataManagementStagingTable\n                        EntityCategory        = $element.EntityCategory\n                        TableGroup            = $element.TableGroup\n                        Field_Name            = $j.Name\n                        Field_Binding         = $field_binding\n                        DataManagementEnabled = $element.DataManagementEnabled\n                    }\n                    $outItems\n                }\n            }\n        }\n    }\n}\n\n#\n# Recurse on the AxQuerySimpleEmbeddedDataSource array used by DataEntity under the AxQuerySimpleRootDataSource to return an array of objects\n#\nFunction QueryDataSourceRecursion ([Microsoft.Dynamics.AX.Metadata.MetaModel.AxQuerySimpleEmbeddedDataSource[]] $queryDataSources) {\n\n    $datasourceList = @()\n    foreach ($datasource in $queryDataSources) {\n\n        $datasourceList += [PsCustomObject]@{ # create a hash table of the name/value pair\n            DataSourceName  = $datasource.Name\n            DataSourceTable = $datasource.Table\n        }\n\n        $datasourceList += QueryDataSourceRecursion $datasource.DataSources\n    }\n\n    $datasourceList\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-axforms.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get Form\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all Forms\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Get-AxForms\n        \n        This will get all objects.\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nFunction Get-AxForms {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    param(\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    BEGIN {\n        Import-GenerateReportAssemblies\n\n        $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n        $providerConfig.XppMetadataPath = $PackageDirectory\n        $providerConfig.MetadataPath = $PackageDirectory\n\n        $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig)\n    }\n\n    PROCESS {\n\n        $formsModelInfos = $metadataProvider.Forms.GetPrimaryKeysWithModelInfo()\n\n        foreach ($tuple in $formsModelInfos) {\n            $elementName = $tuple.Item1\n\n            $element = $metadataProvider.Forms.Read($elementName)\n\n            $outItems = New-Object PSObject -Property @{ # create a hash table of the name/value pair\n                Name        = $element.Name\n                DataSources = $element.DataSources\n            }\n\n            $outItems\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-axviews.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get View\n        \n    .DESCRIPTION\n        Traverse the Dynamics 365 Finance & Operations code repository for all Views\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n        Normally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .EXAMPLE\n        PS C:\\> Get-AxViews\n        \n        This will get all objects.\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n        \n        MIT License\n        \n        Copyright (c) Microsoft Corporation.\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE\n#>\nFunction Get-AxViews {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    param(\n\n        [string] $BinDir = \"$Script:BinDir\\bin\",\n\n        [string] $PackageDirectory = $Script:PackageDirectory\n    )\n\n    BEGIN {\n        Import-GenerateReportAssemblies\n\n        $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration\n        $providerConfig.XppMetadataPath = $PackageDirectory\n        $providerConfig.MetadataPath = $PackageDirectory\n\n        $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n        $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig)\n    }\n\n    PROCESS {\n\n        $viewsModelInfos = $metadataProvider.Views.GetPrimaryKeysWithModelInfo()\n\n        foreach ($tuple in $viewsModelInfos) {\n            $elementName = $tuple.Item1\n\n            $element = $metadataProvider.Views.Read($elementName)\n            \n            $outItems = New-Object PSObject -Property @{ # create a hash table of the name/value pair\n                Name        = $element.Name\n                DataSources = $element.ViewMetadata.DataSources\n\n            }\n\n            $outItems\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-azureserviceobjective.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the Azure Service Objectives\n        \n    .DESCRIPTION\n        Get the current tiering details from the Azure SQL Database instance\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-AzureServiceObjective -DatabaseServer dbserver1.database.windows.net -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\"\n        \n        This will get the Azure service objective details from the Azure SQL Database instance located at \"dbserver1.database.windows.net\"\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-AzureServiceObjective {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseServer,\n\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseName,\n\n        [Parameter(Mandatory = $true)]\n        [string] $SqlUser,\n\n        [Parameter(Mandatory = $true)]\n        [string] $SqlPwd,\n\n        [switch] $EnableException\n    )\n    \n    $Params = Get-DeepClone $PSBoundParameters\n    if($Params.ContainsKey(\"EnableException\")){$null = $Params.Remove(\"EnableException\")}\n\n    $sqlCommand = Get-SqlCommand @Params -TrustedConnection $false\n\n    $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\get-azureserviceobjective.sql\") -join [Environment]::NewLine\n\n    $sqlCommand.CommandText = $commandText\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n\n        $reader = $sqlCommand.ExecuteReader()\n        \n        if ($reader.Read() -eq $true) {\n            Write-PSFMessage -Level Verbose \"Extracting details from the result retrieved from the Azure DB instance\"\n\n            $edition = $reader.GetString(1)\n            $serviceObjective = $reader.GetString(2)\n\n            $reader.close()\n            \n            $sqlCommand.Connection.Close()\n            $sqlCommand.Dispose()\n            \n            [PSCustomObject]@{\n                DatabaseEdition          = $edition\n                DatabaseServiceObjective = $serviceObjective\n            }\n        }\n        else {\n            $messageString = \"The query to detect <c='em'>edition</c> and <c='em'>service objectives</c> from the Azure DB instance <c='em'>failed</c>.\"\n            Write-PSFMessage -Level Host -Message $messageString -Target (Get-SqlString $SqlCommand)\n            Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>','')))\n            return\n        }\n    }\n    catch {\n        $messageString = \"Something went wrong while working against the database.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand)\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_\n        return\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-backupname.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get a backup name for the file\n        \n    .DESCRIPTION\n        Generate a backup name for the file parsed\n        \n    .PARAMETER File\n        Path to the file that you want a backup name for\n        \n    .PARAMETER Suffix\n        The name that you want to put into the new backup file name\n        \n    .EXAMPLE\n        PS C:\\> Get-BackupName -File \"C:\\temp\\d365do.tools\\Test.txt\" -Suffix \"Original\"\n        \n        The function will return \"C:\\temp\\d365do.tools\\Test_Original.txt\"\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-BackupName {\n    [CmdletBinding()]\n    [OutputType([System.String])]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $File,\n\n        [Parameter(Mandatory = $true)]\n        [string] $Suffix\n    )\n\n    Write-PSFMessage -Level Verbose -Message \"Getting backup name for file: $File\" -Tag $File\n\n    $FileInfo = [System.IO.FileInfo]::new($File)\n\n    $BackupName = \"{0}{1}_{2}{3}\" -f $FileInfo.Directory, $FileInfo.BaseName, $Suffix, $FileInfo.Extension\n    \n    Write-PSFMessage -Level Verbose -Message \"Backup name for the file will be $BackupName\" -Tag $BackupName\n    \n    $BackupName\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-canonicalidentityprovider.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Load the Canonical Identity Provider\n        \n    .DESCRIPTION\n        Load the necessary dll files from the D365 instance to get the Canonical Identity Provider object\n        \n    .EXAMPLE\n        PS C:\\> Get-CanonicalIdentityProvider\n        \n        This will get the Canonical Identity Provider from the D365 instance\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-CanonicalIdentityProvider {\n    [CmdletBinding()]\n    param ()\n    try {\n        Write-PSFMessage -Level Verbose \"Loading dll files to do some work against the CanonicalIdentityProvider.\"\n\n        Add-Type -Path \"$Script:AOSPath\\bin\\Microsoft.Dynamics.AX.Framework.EncryptionEngine.dll\"\n        Add-Type -Path \"$Script:AOSPath\\bin\\Microsoft.Dynamics.AX.Security.AuthenticationCommon.dll\"\n\n        Write-PSFMessage -Level Verbose \"Executing the CanonicalIdentityProvider lookup logic.\"\n        $Identity = [Microsoft.Dynamics.AX.Security.AuthenticationCommon.AadHelper]::GetIdentityProvider()\n        $Provider = [Microsoft.Dynamics.AX.Security.AuthenticationCommon.AadHelper]::GetCanonicalIdentityProvider($Identity)\n\n        Write-PSFMessage -Level Verbose \"CanonicalIdentityProvider is: $Provider\" -Tag $Provider\n\n        return $Provider\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while working against the CanonicalIdentityProvider.\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-compilerresult.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Parse the compiler output\n        \n    .DESCRIPTION\n        Parse the output log files from the compiler and show the number of warnings and errors\n        \n    .PARAMETER Path\n        The path to where the compiler output log file is located\n        \n        \n    .EXAMPLE\n        PS C:\\> Get-CompilerResult -Path c:\\temp\\d365fo.tools\\Dynamics.AX.Custom.xppc.log\n        \n        This will analaze the Dynamics.AX.Custom.xppc.log compiler output file.\n        Will create a summarize object with number of errors and warnings.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n        This cmdlet is inspired by the work of \"Vilmos Kintera\" (twitter: @DAXRunBase)\n        \n        All credits goes to him for showing how to extract these information\n        \n        His blog can be found here:\n        https://www.daxrunbase.com/blog/\n        \n        The specific blog post that we based this cmdlet on can be found here:\n        https://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/\n        \n        The github repository containing the original scrips can be found here:\n        https://github.com/DAXRunBase/PowerShell-and-Azure\n        \n#>\nfunction Get-CompilerResult {\n    [CmdletBinding()]\n    [OutputType('[PsCustomObject]')]\n    param (\n        [parameter(Mandatory = $true)]\n        [string] $Path\n    )\n\n    Invoke-TimeSignal -Start\n\n    if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n    $errorText = Select-String -LiteralPath $Path -Pattern ^Errors: | ForEach-Object { $_.Line }\n    $errorCount = [int]$errorText.Split()[-1]\n\n    $warningText = Select-String -LiteralPath $Path -Pattern ^Warnings: | ForEach-Object { $_.Line }\n    $warningCount = [int]$warningText.Split()[-1]\n\n    [PsCustomObject][Ordered]@{\n        File       = \"$Path\"\n        Warnings   = $warningCount\n        Errors     = $errorCount\n        PSTypeName = 'D365FO.TOOLS.CompilerOutput'\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-deepclone.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Clone a hashtable\n        \n    .DESCRIPTION\n        Create a deep clone of a hashtable for you to work on it without updating the original object\n        \n    .PARAMETER InputObject\n        The hashtable you want to clone\n        \n    .EXAMPLE\n        PS C:\\> Get-DeepClone -InputObject $HashTable\n        \n        This will clone the $HashTable variable into a new object and return it to you.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-DeepClone {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')]\n    [CmdletBinding()]\n    param(\n        [parameter(Mandatory = $true)]\n        $InputObject\n    )\n    process\n    {\n        if($InputObject -is [hashtable]) {\n\n            $clone = @{}\n\n            foreach($key in $InputObject.keys)\n            {\n                if($key -eq \"EnableException\") {continue}\n                \n                $clone[$key] = Get-DeepClone $InputObject[$key]\n            }\n\n            $clone\n        } else {\n            $InputObject\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-fileversion.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the file version details\n        \n    .DESCRIPTION\n        Get the file version details for any given file\n        \n    .PARAMETER Path\n        Path to the file that you want to extract the file version details from\n        \n    .EXAMPLE\n        PS C:\\> Get-FileVersion -Path \"C:\\Program Files\\Microsoft Dynamics AX\\60\\Server\\MicrosoftDynamicsAX\\Bin\\AxServ32.exe\"\n        \n        This will get the file version details for the AX AOS executable (AxServ32.exe).\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n        Inspired by https://blogs.technet.microsoft.com/askpfeplat/2014/12/07/how-to-correctly-check-file-versions-with-powershell/\n        \n#>\nfunction Get-FileVersion {\n    [CmdletBinding()]\n    Param(\n        [Parameter(Mandatory = $true)]\n        [string] $Path\n    )\n\n    if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n\n    Write-PSFMessage -Level Verbose -Message \"Extracting the file properties for: $Path\" -Target $Path\n    \n    $Filepath = Get-Item -Path $Path\n\n    [PSCustomObject]@{\n        FileVersion           = $Filepath.VersionInfo.FileVersion\n        ProductVersion        = $Filepath.VersionInfo.ProductVersion\n        FileVersionUpdated    = \"$($Filepath.VersionInfo.FileMajorPart).$($Filepath.VersionInfo.FileMinorPart).$($Filepath.VersionInfo.FileBuildPart).$($Filepath.VersionInfo.FilePrivatePart)\"\n        ProductVersionUpdated = \"$($Filepath.VersionInfo.ProductMajorPart).$($Filepath.VersionInfo.ProductMinorPart).$($Filepath.VersionInfo.ProductBuildPart).$($Filepath.VersionInfo.ProductPrivatePart)\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-identityprovider.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the identity provider\n        \n    .DESCRIPTION\n        Execute a web request to get the identity provider for the given email address\n        \n    .PARAMETER Email\n        Email address on the account that you want to get the Identity Provider details about\n        \n    .EXAMPLE\n        PS C:\\> Get-IdentityProvider -Email \"Claire@contoso.com\"\n        \n        This will get the Identity Provider details for the user account with the email address \"Claire@contoso.com\"\n        \n    .NOTES\n        Author : Rasmus Andersen (@ITRasmus)\n        Author : Mötz Jensen (@splaxi)\n        \n#>\nfunction Get-IdentityProvider {\n    [CmdletBinding()]\n    param(\n        [Parameter(Mandatory = $true, Position = 1)]\n        [string]$Email\n    )\n    $tenant = Get-TenantFromEmail $Email\n\n    try {\n        $webRequest = New-WebRequest \"https://login.windows.net/$tenant/.well-known/openid-configuration\" $null \"GET\"\n\n        $response = $WebRequest.GetResponse()\n\n        if ($response.StatusCode -eq [System.Net.HttpStatusCode]::Ok) {\n\n            $stream = $response.GetResponseStream()\n    \n            $streamReader = New-Object System.IO.StreamReader($stream);\n        \n            $openIdConfig = $streamReader.ReadToEnd()\n            $streamReader.Close();\n        }\n        else {\n            $statusDescription = $response.StatusDescription\n            throw \"Https status code : $statusDescription\"\n        }\n\n        $openIdConfigJSON = ConvertFrom-Json $openIdConfig\n\n        $openIdConfigJSON.issuer\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while executing the web request\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-instanceidentityprovider.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the instance provider from the D365FO instance\n        \n    .DESCRIPTION\n        Get the instance provider from the dll files used for encryption and authentication for D365FO\n        \n    .EXAMPLE\n        PS C:\\> Get-InstanceIdentityProvider\n        \n        This will return the Instance Identity Provider based on the D365FO instance.\n        \n    .NOTES\n        Author : Rasmus Andersen (@ITRasmus)\n        Author : Mötz Jensen (@splaxi)\n        \n#>\nfunction Get-InstanceIdentityProvider {\n    [CmdletBinding()]\n    [OutputType([System.String])]\n    \n    param()\n\n    $files = @(\"$Script:AOSPath\\bin\\Microsoft.Dynamics.AX.Framework.EncryptionEngine.dll\",\n        \"$Script:AOSPath\\bin\\Microsoft.Dynamics.AX.Security.AuthenticationCommon.dll\")\n\n    if (-not (Test-PathExists -Path $files -Type Leaf)) {\n        return\n    }\n\n    try {\n        Add-Type -Path $files\n\n        $Identity = [Microsoft.Dynamics.AX.Security.AuthenticationCommon.AadHelper]::GetIdentityProvider()\n        \n        Write-PSFMessage -Level Verbose -Message \"The found instance identity provider is: $Identity\" -Target $Identity\n\n        $Identity\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while working against the Identity provider\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-instancevalues.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the Azure Database instance values\n        \n    .DESCRIPTION\n        Extract the PlanId, TenantId and PlanCapability from the Azure Database instance\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER TrustedConnection\n        Should the connection use a Trusted Connection or not\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-InstanceValues -DatabaseServer SQLServer -DatabaseName AXDB -SqlUser \"SqlAdmin\" -SqlPwd \"Pass@word1\"\n        \n        This will extract the PlanId, TenantId and PlanCapability from the AXDB on the SQLServer, using the \"SqlAdmin\" credentials to do so.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-InstanceValues {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    [OutputType('System.Collections.Hashtable')]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseServer,\n\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseName,\n\n        [Parameter(Mandatory = $false)]\n        [string] $SqlUser,\n\n        [Parameter(Mandatory = $false)]\n        [string] $SqlPwd,\n\n        [Parameter(Mandatory = $false)]\n        [boolean] $TrustedConnection,\n\n        [switch] $EnableException\n    )\n        \n    $Params = Get-DeepClone $PSBoundParameters\n    if($Params.ContainsKey(\"EnableException\")){$null = $Params.Remove(\"EnableException\")}\n\n    $sqlCommand = Get-SqlCommand @Params\n\n    $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\get-instancevalues.sql\") -join [Environment]::NewLine\n\n    $sqlCommand.CommandText = $commandText\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n\n        $reader = $sqlCommand.ExecuteReader()\n        \n        if ($reader.Read() -eq $true) {\n            Write-PSFMessage -Level Verbose \"Extracting details from the result retrieved from the DB instance\"\n\n            $tenantId = $reader.GetString(0)\n            $planId = $reader.GetGuid(1)\n            $planCapability = $reader.GetString(2)\n\n            @{\n                TenantId       = $tenantId\n                PlanId         = $planId\n                PlanCapability = $planCapability\n            }\n        }\n        else {\n            $messageString = \"The query to detect <c='em'>TenantId</c>, <c='em'>PlanId</c> and <c='em'>PlanCapability</c> from the database <c='em'>failed</c>.\"\n            Write-PSFMessage -Level Host -Message $messageString -Target (Get-SqlString $SqlCommand)\n            Stop-PSFFunction -Message \"Stopping because of missing parameters.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>','')))\n            return\n        }\n    }\n    catch {\n        $messageString = \"Something went wrong while working against the database.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand)\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_\n        return\n    }\n    finally {\n        $reader.close()\n            \n        $sqlCommand.Connection.Close()\n        $sqlCommand.Dispose()\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-lcsassetfilev2.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get information for all assets of a type from the asset library inside a LCS project\n        \n    .DESCRIPTION\n        Get the information for the available file assets of a certain type from the asset library inside a LCS project\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER FileType\n        Type of asset you want to get information for\n        \n        Valid options:\n        \"Model\"\n        \"Process Data Package\"\n        \"Software Deployable Package\"\n        \"GER Configuration\"\n        \"Data Package\"\n        \"PowerBI Report Model\"\n        \"E-Commerce Package\"\n        \"NuGet Package\"\n        \"Retail Self-Service Package\"\n        \"Commerce Cloud Scale Unit Extension\"\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-LcsAssetFileV2 -ProjectId 123456789 -FileType SoftwareDeployablePackage -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will get all software deployable packages from the Asset Library inside LCS.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The FileType is Software Deployable Packages, with the FileType parameter.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .NOTES\n        Tags: Environment, LCS, Api, AAD, Token, Asset, File, Files\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Get-LcsAssetFileV2 {\n    [Cmdletbinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [int] $ProjectId,\n\n        [LcsAssetFileType] $FileType,\n\n        [Alias('Token')]\n        [string] $BearerToken,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n        \n        $fileTypeValue = [int]$FileType\n        \n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"GET\"\n        $parms.Uri = \"$LcsApiUri/box/fileasset/GetAssets/$($ProjectId)?fileType=$($fileTypeValue)\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n    }\n\n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in request for listing files from the asset library of LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-lcsassetvalidationstatusv2.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the validation status from LCS\n        \n    .DESCRIPTION\n        Get the validation status for a given file in the Asset Library in LCS\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER AssetId\n        The unique id of the asset / file that you are trying to deploy from LCS\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-LcsAssetValidationStatusV2 -ProjectId 123456789 -BearerToken \"JldjfafLJdfjlfsalfd...\" -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will check the file with the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" in validated or not.\n        It will test against the Asset Library located under the LCS project 123456789.\n        The BearerToken \"JldjfafLJdfjlfsalfd...\" is used to authenticate against the LCS API endpoint.\n        The file will be named \"ReadyForTesting\" inside the Asset Library in LCS.\n        The file is validated against the NON-EUROPE LCS API.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Get-LcsAssetValidationStatusV2 {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [int] $ProjectId,\n        \n        [Parameter(Mandatory = $true)]\n        [Alias('Token')]\n        [string] $BearerToken,\n\n        [Parameter(Mandatory = $true)]\n        [string] $AssetId,\n\n        [Parameter(Mandatory = $true)]\n        [string] $LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n        \n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"GET\"\n        $parms.Uri = \"$LcsApiUri/box/fileasset/GetFileAssetValidationStatus/$($ProjectId)?assetId=$AssetId\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n    }\n\n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in request for getting the validation status of an asset in the asset library of LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-lcsdatabasebackupsv2.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get database backups from LCS project\n        \n    .DESCRIPTION\n        Get the available database backups from the Asset Library in LCS project\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-LcsDatabaseBackupsV2 -ProjectId 123456789 -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will get all available database backups from the Asset Library inside LCS.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .NOTES\n        Tags: Environment, LCS, Api, AAD, Token, Bacpac, Backup\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Get-LcsDatabaseBackupsV2 {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [Cmdletbinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [int] $ProjectId,\n    \n        [Alias('Token')]\n        [string] $BearerToken,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n    \n    begin {\n        Invoke-TimeSignal -Start\n        \n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"GET\"\n        $parms.Uri = \"$LcsApiUri/databasemovement/v1/databases/project/$($ProjectId)\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n    }\n\n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in request for listing all backup files from the asset library of LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-lcsdatabaseoperationstatusv2.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the status of a LCS database operation\n        \n    .DESCRIPTION\n        Get the database operation status for an environment in LCS\n        \n    .PARAMETER Token\n        The token to be used for the http request against the LCS API\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER OperationActivityId\n        The unique id of the action you got from when starting the database operation against the environment\n        \n    .PARAMETER EnvironmentId\n        The unique id of the environment that you want to work against\n        \n        The Id can be located inside the LCS portal\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-LcsDatabaseOperationStatusV2 -ProjectId 123456789 -OperationActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -Token \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will check the database operation status of a specific OperationActivityId against an environment.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .LINK\n        Start-LcsDatabaseRefresh\n        \n    .NOTES\n        Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token, Deployment, Deployable Package\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Get-LcsDatabaseOperationStatusV2 {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Cmdletbinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [int] $ProjectId,\n    \n        [Alias('Token')]\n        [string] $BearerToken,\n\n        [Parameter(Mandatory = $true)]\n        [string] $OperationActivityId,\n\n        [Parameter(Mandatory = $true)]\n        [string] $EnvironmentId,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n    \n    begin {\n        Invoke-TimeSignal -Start\n        \n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"GET\"\n        $parms.Uri = \"$LcsApiUri/databasemovement/v1/fetchstatus/project/$($ProjectId)/environment/$($EnvironmentId)/operationactivity/$($OperationActivityId)\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n    }\n\n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in request for getting the status of a database operation in LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-lcsdeploymentstatusv2.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the status of a LCS deployment\n        \n    .DESCRIPTION\n        Get the deployment status for an environment in LCS\n        \n    .PARAMETER Token\n        The token to be used for the http request against the LCS API\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER ActivityId\n        The unique id of the action you got from when starting the deployment to the environment\n        \n    .PARAMETER EnvironmentId\n        The unique id of the environment that you want to work against\n        \n        The Id can be located inside the LCS portal\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-LcsDeploymentStatusV2 -ProjectId 123456789 -Token \"Bearer JldjfafLJdfjlfsalfd...\" -ActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will start the deployment of the file located in the Asset Library with the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" in the LCS project with Id 123456789.\n        The http request will be using the \"Bearer JldjfafLJdfjlfsalfd...\" token for authentication against the LCS API.\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .LINK\n        Start-LcsDeployment\n        \n    .NOTES\n        Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token, Deployment, Deployable Package\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Get-LcsDeploymentStatusV2 {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Cmdletbinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [int] $ProjectId,\n    \n        [Alias('Token')]\n        [string] $BearerToken,\n\n        [Parameter(Mandatory = $true)]\n        [string] $ActivityId,\n\n        [Parameter(Mandatory = $true)]\n        [string] $EnvironmentId,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n        \n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"GET\"\n        $parms.Uri = \"$LcsApiUri/environment/v2/fetchstatus/project/$($ProjectId)/environment/$($EnvironmentId)/operationactivity/$($ActivityId)\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n    }\n\n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in request for getting the status of a deployment in LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-lcsenvironmenthistory.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get history for a given environment within a LCS project\n        \n    .DESCRIPTION\n        Get history details for a given environment from within a LCS project\n        \n        There can be multiple pages of data, which requires you to use the TraverseAllPages parameter, if you want all data to be shown\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER EnvironmentId\n        The unique id of the environment that you want to work against\n        \n        The Id can be located inside the LCS portal\n        \n    .PARAMETER Page\n        Page number that you want to request from the LCS API\n        \n        This is part of the initial request, which helps you navigate more data - when it is available\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-LcsEnvironmentHistory -ProjectId 123456789 -Token \"Bearer JldjfafLJdfjlfsalfd...\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will list the first page of environment history data from the LCS API.\n        The ProjectId \"123456789\" is the desired project.\n        The Token \"Bearer JldjfafLJdfjlfsalfd...\" is the authentication to be used.\n        The EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" is the specific environment that we want history data from.\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Get-LcsEnvironmentHistory {\n    [CmdletBinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [int] $ProjectId,\n    \n        [Alias('Token')]\n        [string] $BearerToken,\n\n        [string] $EnvironmentId,\n\n        [int] $Page,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n        \n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"GET\"\n        $parms.Uri = \"$LcsApiUri/environmentinfo/v1/history/project/$($ProjectId)/environment/$EnvironmentId\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n\n        if ($Page) {\n            $parms.Uri += \"/?page=$Page\"\n        }\n    }\n\n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in request for getting the environment history in LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-lcsenvironmentmetadata.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get LCS environment meta data from within a project\n        \n    .DESCRIPTION\n        Get all meta data details for environments from within a LCS project\n        \n        It supports listing all environments, but also supports single / specific environments by searching based on EnvironmentId or EnvironmentName\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER EnvironmentId\n        The unique id of the environment that you want to work against\n        \n        The Id can be located inside the LCS portal\n        \n        Either you want to utilize the EnvironmentId parameter or you can utilize the EnvironmentName parameter, only one of them is valid in a request\n        \n    .PARAMETER EnvironmentName\n        The unique name of the environment that you want to work against\n        \n        The Id can be located inside the LCS portal\n        \n        Either you want to utilize the EnvironmentName parameter or you can utilize the EnvironmentId parameter, only one of them is valid in a request\n        \n    .PARAMETER Page\n        Page number that you want to request from the LCS API\n        \n        This is part of the initial request, which helps you navigate more data - when it is available\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-LcsEnvironmentMetadata -ProjectId 123456789 -Token \"Bearer JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will list the first page of environment metadata from the LCS API, across all available environments.\n        The ProjectId \"123456789\" is the desired project.\n        The Token \"Bearer JldjfafLJdfjlfsalfd...\" is the authentication to be used.\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .EXAMPLE\n        PS C:\\> Get-LcsEnvironmentMetadata -ProjectId 123456789 -Token \"Bearer JldjfafLJdfjlfsalfd...\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will list the first page of environment metadata from the LCS API.\n        The ProjectId \"123456789\" is the desired project.\n        The Token \"Bearer JldjfafLJdfjlfsalfd...\" is the authentication to be used.\n        The EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" is the specific environment that we want metadata from.\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .EXAMPLE\n        PS C:\\> Get-LcsEnvironmentMetadata -ProjectId 123456789 -Token \"Bearer JldjfafLJdfjlfsalfd...\" -EnvironmentName \"Contoso-SIT\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will list the first page of environment metadata from the LCS API.\n        The ProjectId \"123456789\" is the desired project.\n        The Token \"Bearer JldjfafLJdfjlfsalfd...\" is the authentication to be used.\n        The EnvironmentName \"Contoso-SIT\" is the specific environment that we want metadata from.\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Get-LcsEnvironmentMetadata {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    # [CmdletBinding()]\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param(\n        [Parameter(Mandatory = $true)]\n        [int] $ProjectId,\n    \n        [Alias('Token')]\n        [string] $BearerToken,\n\n        [Parameter(ParameterSetName = 'SearchByEnvironmentId')]\n        [string] $EnvironmentId,\n\n        [Parameter(ParameterSetName = 'SearchByEnvironmentName')]\n        [string] $EnvironmentName,\n\n        [Parameter(ParameterSetName = 'Pagination')]\n        [int] $Page,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n        \n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"GET\"\n        $parms.Uri = \"$LcsApiUri/environmentinfo/v1/detail/project/$($ProjectId)\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n\n        if ($PSCmdlet.ParameterSetName -eq \"Pagination\") {\n            $parms.Uri += \"/?page=$Page\"\n        }\n        elseif ($PSCmdlet.ParameterSetName -eq \"SearchByEnvironmentId\") {\n            $parms.Uri += \"/?environmentId=$EnvironmentId\"\n        }\n        elseif ($PSCmdlet.ParameterSetName -eq \"SearchByEnvironmentName\") {\n            $parms.Uri += \"/?environmentName=$EnvironmentName\"\n        }\n    }\n\n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in request for getting the environment metadata a project in LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-lcsenvironmentrsatcertificate.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get LCS environment rsat certificate from within a project\n        \n    .DESCRIPTION\n        Download and persist the active rsat certificate from environments from within a LCS project\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER EnvironmentId\n        The unique id of the environment that you want to work against\n        \n        The Id can be located inside the LCS portal\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Get-LcsEnvironmentRsatCertificate -ProjectId 123456789 -Token \"Bearer JldjfafLJdfjlfsalfd...\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will get the raw rsat details for the environment from the LCS API.\n        The ProjectId \"123456789\" is the desired project.\n        The Token \"Bearer JldjfafLJdfjlfsalfd...\" is the authentication to be used.\n        The EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" is the specific environment that we want the rsat certificate details from.\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-LcsEnvironmentRsatCertificate {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    # [CmdletBinding()]\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    param(\n        [Parameter(Mandatory = $true)]\n        [int] $ProjectId,\n    \n        [Alias('Token')]\n        [Parameter(Mandatory = $true)]\n        [string] $BearerToken,\n\n        [Parameter(Mandatory = $true)]\n        [string] $EnvironmentId,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n        \n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"GET\"\n        $parms.Uri = \"$LcsApiUri/environmentinfo/v1/rsatdownload/project/$($ProjectId)/environment/$EnvironmentId\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n    }\n\n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in request for getting the environment rsat certificate in LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-lcsfileasset.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get information for a single asset from the project or shared asset library of LCS\n        \n    .DESCRIPTION\n        Get the information for an available file asset from the project or shared asset library of LCS\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER AssetId\n        Id of the asset you want to get information for\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        Usually this parameter is not used directly, but via the Enable-D365Exception cmdlet\n        See https://github.com/d365collaborative/d365fo.tools/wiki/Exception-handling#what-does-the--enableexception-parameter-do for further information\n        \n    .EXAMPLE\n        PS C:\\> Get-LcsFileAsset -ProjectId 123456789 -AssetId \"e70cac82-6a7c-4f9e-a8b9-e707b961e986\" -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will get the information of the asset identified by the asset id.\n        The asset can either be part of the project asset library or the shared asset library. Note that in both cases, the project id is required.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .NOTES\n        Tags: Environment, LCS, Api, AAD, Token, Asset, File, Files\n        \n        Author: Florian Hopfner (@FH-Inway)\n#>\n\nfunction Get-LcsFileAsset {\n    [Cmdletbinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [int] $ProjectId,\n\n        [Parameter(Mandatory = $true)]\n        [string] $AssetId,\n\n        [Alias('Token')]\n        [string] $BearerToken,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n        \n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"GET\"\n        $parms.Uri = \"$LcsApiUri/box/fileasset/GetFileAsset/$($ProjectId)?assetId=$($AssetId)\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n    }\n\n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in request for file asset from the shared asset library of LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-lcssharedassetfile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get information for all assets of a type from the shared asset library of LCS\n        \n    .DESCRIPTION\n        Get the information for the available file assets of a certain type from the shared asset library of LCS\n        \n    .PARAMETER FileType\n        Type of file you want to get information for\n        \n        Valid options:\n        \"Model\"\n        \"Process Data Package\"\n        \"Software Deployable Package\"\n        \"GER Configuration\"\n        \"Data Package\"\n        \"PowerBI Report Model\"\n        \"E-Commerce Package\"\n        \"NuGet Package\"\n        \"Retail Self-Service Package\"\n        \"Commerce Cloud Scale Unit Extension\"\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on which LCS shared asset library you want to query. There are multiple valid URI's / URL's.\n        Not that not all file types may be available in all URIs.\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        Usually this parameter is not used directly, but via the Enable-D365Exception cmdlet\n        See https://github.com/d365collaborative/d365fo.tools/wiki/Exception-handling#what-does-the--enableexception-parameter-do for further information\n        \n    .EXAMPLE\n        PS C:\\> Get-LcsSharedAssetFile -FileType SoftwareDeployablePackage -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will get all software deployable packages from the shared asset library of LCS.\n        The FileType is Software Deployable Packages, with the FileType parameter.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .NOTES\n        Tags: Environment, LCS, Api, AAD, Token, Asset, File, Files\n        \n        Author: Florian Hopfner (@FH-Inway)\n#>\n\nfunction Get-LcsSharedAssetFile {\n    [Cmdletbinding()]\n    param(\n        [LcsAssetFileType] $FileType,\n\n        [Alias('Token')]\n        [string] $BearerToken,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n        \n        $fileTypeValue = [int]$FileType\n        \n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"GET\"\n        $parms.Uri = \"$LcsApiUri/box/fileasset/GetSharedAssets?fileType=$($fileTypeValue)\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n    }\n\n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in request for listing files from the shared asset library of LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-loginfromemail.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the login name from the e-mail address\n        \n    .DESCRIPTION\n        Extract the login name from the e-mail address by substring everything before the @ character\n        \n    .PARAMETER Email\n        The e-mail address that you want to get the login name from\n        \n    .EXAMPLE\n        PS C:\\> Get-LoginFromEmail -Email Claire@contoso.com\n        \n        This will substring the e-mail address and return \"Claire\" as the result\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-LoginFromEmail {\n    [CmdletBinding()]\n    [OutputType('System.String')]\n    param (\n        [string]$Email\n    )\n\n    $email.Substring(0, $Email.LastIndexOf('@')).Trim()\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-networkdomain.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the network domain from the e-mail\n        \n    .DESCRIPTION\n        Get the network domain provider (Azure) for the e-mail / user\n        \n    .PARAMETER Email\n        The e-mail that you want to retrieve the provider for\n        \n    .EXAMPLE\n        PS C:\\> Get-NetworkDomain -Email \"Claire@contoso.com\"\n        \n        This will return the provider registered with the \"Claire@contoso.com\" e-mail address.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-NetworkDomain {\n    [CmdletBinding()]\n    [OutputType('System.String')]\n    param(\n        [Parameter(Mandatory = $true, Position = 1)]\n        [string]$Email\n    )\n\n    $tenant = Get-TenantFromEmail $Email\n    $provider = Get-InstanceIdentityProvider\n    $canonicalIdentityProvider = Get-CanonicalIdentityProvider\n\n    if ($Provider.ToLower().Contains($Tenant.ToLower()) -eq $True) {\n        $canonicalIdentityProvider\n    }\n    else {\n        \"$canonicalIdentityProvider$Tenant\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-productinfoprovider.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the product information\n        \n    .DESCRIPTION\n        Get the product information object from the environment\n        \n    .EXAMPLE\n        PS C:\\> Get-ProductInfoProvider\n        \n        This will get the product information object and return it\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-ProductInfoProvider {\n    #!HACK: This can't be solved like we use to - it loads dependent assemblies based on path, when you invoke the method.\n    Add-Type -Path \"$Script:AOSPath\\bin\\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.dll\"\n\n    [Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.ProductInfoProvider]::get_Provider()\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-servicelist.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the list of Dynamics 365 services\n        \n    .DESCRIPTION\n        Get the list of Dynamics 365 service names based on the parameters\n        \n    .PARAMETER All\n        Switch to instruct the cmdlet to output all service names\n        \n    .PARAMETER Aos\n        Switch to instruct the cmdlet to output the aos service name\n        \n    .PARAMETER Batch\n        Switch to instruct the cmdlet to output the batch service name\n        \n    .PARAMETER FinancialReporter\n        Switch to instruct the cmdlet to output the financial reporter service name\n        \n    .PARAMETER DMF\n        Switch to instruct the cmdlet to output the data management service name\n        \n    .EXAMPLE\n        PS C:\\> Get-ServiceList -All\n        \n        This will return all services for an D365 environment\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nFunction Get-ServiceList {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidDefaultValueSwitchParameter\", \"\")]\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    \n    param (\n        [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )]\n        [switch] $All = $true,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 2 )]\n        [switch] $Aos,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 3 )]\n        [switch] $Batch,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 4 )]\n        [switch] $FinancialReporter,\n\n        [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 5 )]\n        [switch] $DMF\n    )\n\n    if ($PSCmdlet.ParameterSetName -eq \"Specific\") {\n        $All = $false\n    }\n\n    Write-PSFMessage -Level Verbose -Message \"The PSBoundParameters was\" -Target $PSBoundParameters\n\n    $aosname = \"w3svc\"\n    $batchname = \"DynamicsAxBatch\"\n    $financialname = \"MR2012ProcessService\"\n    $dmfname = \"Microsoft.Dynamics.AX.Framework.Tools.DMF.SSISHelperService.exe\"\n\n    [System.Collections.ArrayList]$Services = New-Object -TypeName \"System.Collections.ArrayList\"\n\n    if ($All) {\n        $null = $Services.AddRange(@($aosname, $batchname, $financialname, $dmfname))\n    }\n    else {\n        if ($Aos) {\n            $null = $Services.Add($aosname)\n        }\n        if ($Batch) {\n            $null = $Services.Add($batchname)\n        }\n        if ($FinancialReporter) {\n            $null = $Services.Add($financialname)\n        }\n        if ($DMF) {\n            $null = $Services.Add($dmfname)\n        }\n    }\n\n    $Services.ToArray()\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-sqlcommand.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get a SqlCommand object\n        \n    .DESCRIPTION\n        Get a SqlCommand object initialized with the passed parameters\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER TrustedConnection\n        Should the connection use a Trusted Connection or not\n        \n    .PARAMETER NoPooling\n        Should the connection use connection pooling or not\n        \n    .EXAMPLE\n        PS C:\\> Get-SqlCommand -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\" -TrustedConnection $true\n        \n        This will initialize a new SqlCommand object (.NET type) with localhost as the server name, AxDB as the database and the User123 sql credentials.\n        \n    .EXAMPLE\n        PS C:\\> Get-SqlCommand -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\" -TrustedConnection $true -NoPooling\n        \n        This will initialize a new SqlCommand object (.NET type) with localhost as the server name, AxDB as the database and the User123 sql credentials.\n        The connection will not use connection pooling.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-SQLCommand {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseServer,\n\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseName,\n\n        [Parameter(Mandatory = $false)]\n        [string] $SqlUser,\n\n        [Parameter(Mandatory = $false)]\n        [string] $SqlPwd,\n\n        [Parameter(Mandatory = $false)]\n        [boolean] $TrustedConnection,\n\n        [switch] $NoPooling\n    )\n\n    Write-PSFMessage -Level Debug -Message \"Writing the bound parameters\" -Target $PsBoundParameters\n    [System.Collections.ArrayList]$Params = New-Object -TypeName \"System.Collections.ArrayList\"\n\n    $null = $Params.Add(\"Server='$DatabaseServer';\")\n    $null = $Params.Add(\"Database='$DatabaseName';\")\n    \n    # We have learned that closing a connection is not enough to closing the connection.\n    if ($NoPooling) { $null = $Params.Add(\"Pooling=false;\") }\n\n    if ($null -eq $TrustedConnection -or (-not $TrustedConnection)) {\n        $null = $Params.Add(\"User='$SqlUser';\")\n        $null = $Params.Add(\"Password='$SqlPwd';\")\n    }\n    else {\n        $null = $Params.Add(\"Integrated Security='SSPI';\")\n    }\n\n    $null = $Params.Add(\"Application Name='d365fo.tools'\")\n    \n    Write-PSFMessage -Level Verbose -Message \"Building the SQL connection string.\" -Target ($Params -join \",\")\n    $sqlConnection = New-Object System.Data.SqlClient.SqlConnection\n\n    try {\n        $sqlConnection.ConnectionString = ($Params -join \"\")\n\n        $sqlCommand = New-Object System.Data.SqlClient.SqlCommand\n        $sqlCommand.Connection = $sqlConnection\n        $sqlCommand.CommandTimeout = 0\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while working with the sql server connection objects\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n    \n    $sqlCommand\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-sqlparametersize.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the size from the parameter\n        \n    .DESCRIPTION\n        Get the size from the parameter based on its datatype and value\n        \n    .PARAMETER SqlParameter\n        The SqlParameter object that you want to get the size from\n        \n    .EXAMPLE\n        PS C:\\> $SqlCmd = New-Object System.Data.SqlClient.SqlCommand\n        PS C:\\> $SqlCmd.Parameters.AddWithValue(\"@Parm1\", \"1234\")\n        PS C:\\> Get-SqlParameterSize -SqlParameter $SqlCmd.Parameters[0]\n        \n        This will extract the size from the first parameter from the SqlCommand object and return it as a formatted string.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-SqlParameterSize {\n    [CmdletBinding()]\n    [OutputType('System.String')]\n    param (\n        [System.Data.SqlClient.SqlParameter] $SqlParameter\n    )\n\n    $res = \"\"\n\n    $stringSizeTypes = @(\n        [System.Data.SqlDbType]::Char,\n        [System.Data.SqlDbType]::NChar,\n        [System.Data.SqlDbType]::NText,\n        [System.Data.SqlDbType]::NVarChar,\n        [System.Data.SqlDbType]::Text,\n        [System.Data.SqlDbType]::VarChar\n    )\n\n    if ( $stringSizeTypes -contains $SqlParameter.SqlDbType) {\n        $res = \"($($SqlParameter.Size))\"\n    }\n\n    $res\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-sqlparametervalue.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the value from the parameter\n        \n    .DESCRIPTION\n        Get the value that is assigned to the SqlParameter object\n        \n    .PARAMETER SqlParameter\n        The SqlParameter object that you want to work against\n        \n    .EXAMPLE\n        PS C:\\> $SqlCmd = New-Object System.Data.SqlClient.SqlCommand\n        PS C:\\> $SqlCmd.Parameters.AddWithValue(\"@Parm1\", \"1234\")\n        PS C:\\> Get-SqlParameterValue -SqlParameter $SqlCmd.Parameters[0]\n        \n        This will extract the value from the first parameter from the SqlCommand object.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-SqlParameterValue {\n    [CmdletBinding()]\n    [OutputType('System.String')]\n    param (\n        [System.Data.SqlClient.SqlParameter] $SqlParameter\n    )\n\n    $result = $null\n\n    $stringEscaped = @(\n        [System.Data.SqlDbType]::Char,\n        [System.Data.SqlDbType]::DateTime,\n        [System.Data.SqlDbType]::NChar,\n        [System.Data.SqlDbType]::NText,\n        [System.Data.SqlDbType]::NVarChar,\n        [System.Data.SqlDbType]::Text,\n        [System.Data.SqlDbType]::VarChar,\n        [System.Data.SqlDbType]::Xml,\n        [System.Data.SqlDbType]::Date,\n        [System.Data.SqlDbType]::Time,\n        [System.Data.SqlDbType]::DateTime2,\n        [System.Data.SqlDbType]::DateTimeOffset\n    )\n\t\n    $stringNumbers = @([System.Data.SqlDbType]::Float, [System.Data.SqlDbType]::Decimal)\n\t\n    switch ($SqlParameter.SqlDbType) {\n        { $stringEscaped -contains $_ } {\n            $result = \"'{0}'\" -f $SqlParameter.Value.ToString().Replace(\"'\", \"''\")\n            break\n        }\n\n        { [System.Data.SqlDbType]::Bit } {\n            if ((ConvertTo-BooleanOrDefault -Object $SqlParameter.Value.ToString() -Default $true)) {\n                $result = '1'\n            }\n            else {\n                $result = '0'\n            }\n                        \n            break\n        }\n\t\t\n        { $stringNumbers -contains $_ } {\n            $SqlParameter.Value\n            $result = ([System.Double]$SqlParameter.Value).ToString([System.Globalization.CultureInfo]::InvariantCulture).Replace(\"'\", \"''\")\n            break\n        }\n\n        default {\n            $result = $SqlParameter.Value.ToString().Replace(\"'\", \"''\")\n            break\n        }\n    }\n\n    $result\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-sqlstring.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get an executable string from a SqlCommand object\n        \n    .DESCRIPTION\n        Get an formatted and valid string from a SqlCommand object that contains all variables\n        \n    .PARAMETER SqlCommand\n        The SqlCommand object that you want to retrieve the string from\n        \n    .EXAMPLE\n        PS C:\\> $SqlCmd = New-Object System.Data.SqlClient.SqlCommand\n        PS C:\\> $SqlCmd.CommandText = \"SELECT * FROM Table WHERE Column = @Parm1\"\n        PS C:\\> $SqlCmd.Parameters.AddWithValue(\"@Parm1\", \"1234\")\n        PS C:\\> Get-SqlString -SqlCommand $SqlCmd\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-SqlString {\n    [CmdletBinding()]\n    [OutputType('System.String')]\n    param (\n        [System.Data.SqlClient.SqlCommand] $SqlCommand\n    )\n\n\t$sbDeclare = [System.Text.StringBuilder]::new()\n\t$sbAssignment = [System.Text.StringBuilder]::new()\n\t$sbRes = [System.Text.StringBuilder]::new()\n\n    if ($SqlCommand.CommandType -eq [System.Data.CommandType]::Text) {\n        if (-not ($null -eq $SqlCommand.Connection)) {\n            $null = $sbDeclare.Append(\"USE [\").Append($SqlCommand.Connection.Database).AppendLine(\"]\")\n        }\n\n        foreach ($parameter in $SqlCommand.Parameters) {\n            if ($parameter.Direction -eq [System.Data.ParameterDirection]::Input) {\n                $null = $sbDeclare.Append(\"DECLARE \").Append($parameter.ParameterName).Append(\"`t\")\n                $null = $sbDeclare.Append($parameter.SqlDbType.ToString().ToUpper())\n                $null = $sbDeclare.AppendLine((Get-SqlParameterSize -SqlParameter $parameter))\n\n                $null = $sbAssignment.Append(\"SET \").Append($parameter.ParameterName).Append(\" = \").AppendLine((Get-SqlParameterValue -SqlParameter $parameter))\n\t\t\t}\n        }\n        \n        $null = $sbRes.AppendLine($sbDeclare.ToString())\n        $null = $sbRes.AppendLine($sbAssignment.ToString())\n        $null = $sbRes.AppendLine($SqlCommand.CommandText)\n\t}\n\n\t$sbRes.ToString()\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-syncelements.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Retrieve sync base and extension elements based on a modulename\n        \n    .DESCRIPTION\n        Retrieve the list of installed packages / modules where the name fits the ModuleName parameter.\n        For every model retrieved: collect all base sync and extension sync elements.\n        \n    .PARAMETER ModuleName\n        Name of the module that you are looking for\n        \n        Accepts wildcards for searching. E.g. -Name \"Application*Adaptor\"\n        \n        Default value is \"*\" which will search for all modules\n        \n    .EXAMPLE\n        PS C:\\> Get-SyncElements -ModuleName \"Application*Adaptor\"\n        \n        Retrieve the list of installed packages / modules where the name fits the search \"Application*Adaptor\".\n        For every model retrieved: collect all base sync and extension sync elements.\n        \n    .NOTES\n        Tags: Database\n        \n        Author: Jasper Callens - Cegeka\n        \n#>\nfunction Get-SyncElements {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    Param(\n        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]\n        [string] $ModuleName\n    )\n\n    begin {\n        $assemblies2Process = New-Object -TypeName \"System.Collections.ArrayList\"\n                \n        $null = $assemblies2Process.Add((Join-Path $BinDirTools \"Microsoft.Dynamics.AX.Metadata.dll\"))\n        $null = $assemblies2Process.Add((Join-Path $BinDirTools \"Microsoft.Dynamics.AX.Metadata.Core.dll\"))\n        $null = $assemblies2Process.Add((Join-Path $BinDirTools \"Microsoft.Dynamics.AX.Metadata.Storage.dll\"))\n        $null = $assemblies2Process.Add((Join-Path $BinDirTools \"Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll\"))\n        $null = $assemblies2Process.Add((Join-Path $BinDirTools \"Microsoft.Dynamics.AX.Metadata.Management.Delta.dll\"))\n        $null = $assemblies2Process.Add((Join-Path $BinDirTools \"Microsoft.Dynamics.AX.Metadata.Management.Core.dll\"))\n        $null = $assemblies2Process.Add((Join-Path $BinDirTools \"Microsoft.Dynamics.AX.Metadata.Management.Merge.dll\"))\n        $null = $assemblies2Process.Add((Join-Path $BinDirTools \"Microsoft.Dynamics.AX.Metadata.Management.Diff.dll\"))\n\n        Import-AssemblyFileIntoMemory -Path $($assemblies2Process.ToArray())\n\n        $runtimeMetadataProvider = (New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory).CreateRuntimeProvider($Script:PackageDirectory)\n\n        $baseSyncElements = New-Object -TypeName \"System.Collections.ArrayList\"\n        $extensionSyncElements = New-Object -TypeName \"System.Collections.ArrayList\"\n\n        $extensionToBaseSyncElements = New-Object -TypeName \"System.Collections.ArrayList\"\n    }\n\n    process {\n        Write-PSFMessage -Level Debug -Message \"Collecting $ModuleName AOT elements to sync\"\n\n        $baseSyncElements.AddRange($runtimeMetadataProvider.Tables.ListObjects($ModuleName));\n        $baseSyncElements.AddRange($runtimeMetadataProvider.Views.ListObjects($ModuleName));\n        $baseSyncElements.AddRange($runtimeMetadataProvider.DataEntityViews.ListObjects($ModuleName));\n\n        $extensionSyncElements.AddRange($runtimeMetadataProvider.TableExtensions.ListObjects($ModuleName));\n\n        # Some Extension elements have to be 'converted' to their base element that has to be passed to the SyncList of the syncengine\n        # Add these elements to an ArrayList\n        $extensionToBaseSyncElements.AddRange($runtimeMetadataProvider.ViewExtensions.ListObjects($ModuleName));\n        $extensionToBaseSyncElements.AddRange($runtimeMetadataProvider.DataEntityViewExtensions.ListObjects($ModuleName));\n    }\n\n    end {\n        # Loop every extension element, convert it to its base element and add the base element to another list\n        Foreach ($extElement in $extensionToBaseSyncElements) {\n            $null = $baseSyncElements.Add($extElement.Substring(0, $extElement.IndexOf('.')))\n        }\n\n        Write-PSFMessage -Level Debug -Message \"Elements from $ModuleName retrieved: $(($baseSyncElements + $extensionSyncElements) -join \",\")\"\n\n        [PSCustomObject]@{\n            BaseSyncElements = $baseSyncElements.ToArray();\n            ExtensionSyncElements = $extensionSyncElements.ToArray();\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-tenantfromemail.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the tenant from e-mail address\n        \n    .DESCRIPTION\n        Get the tenant (domain) from an e-mail address\n        \n    .PARAMETER Email\n        The e-mail address you want to get the tenant from\n        \n    .EXAMPLE\n        PS C:\\> Get-TenantFromEmail -Email \"Claire@contoso.com\"\n        \n        This will return the tenant (domain) from the \"Claire@contoso.com\" e-mail address.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-TenantFromEmail {\n    [CmdletBinding()]\n    [OutputType('System.String')]\n    param (\n        [string] $email\n    )\n\n    $email.Substring($email.LastIndexOf('@') + 1).Trim();\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-timezone.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get time zone\n        \n    .DESCRIPTION\n        Extract the time zone object from the supplied parameter\n        \n        Uses regex to determine whether or not the parameter is the ID or the DisplayName of a time zone\n        \n    .PARAMETER InputObject\n        String value that you want converted into a time zone object\n        \n    .EXAMPLE\n        PS C:\\> Get-TimeZone -InputObject \"UTC\"\n        \n        This will return the time zone object based on the UTC id.\n        \n    .NOTES\n        Tag: Time, TimeZone,\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Get-TimeZone {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidOverwritingBuiltInCmdlets\", \"\")]\n    [CmdletBinding()]\n    [OutputType('System.TimeZoneInfo')]\n    param (\n        [Parameter(Mandatory = $true, Position = 1)]\n        [string] $InputObject\n    )\n\n    if ($InputObject -match \"\\s\\-\\s\\[\") {\n        $search = [regex]::Split($InputObject, \"\\s\\-\\s\\[\")[0]\n\n        [System.TimeZoneInfo]::GetSystemTimeZones() | Where-Object {$PSItem.DisplayName -eq $search} | Select-Object -First 1\n    }\n    else {\n        try {\n            [System.TimeZoneInfo]::FindSystemTimeZoneById($InputObject)\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Unable to translate the <c='em'>$InputObject</c> to a known .NET timezone value. Please make sure you filled in a valid timezone.\"\n            Stop-PSFFunction -Message \"Stopping because timezone wasn't found.\" -StepsUpward 1\n            return\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-usersidfromaad.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get the SID from an Azure Active Directory (AAD) user\n        \n    .DESCRIPTION\n        Get the generated SID that an Azure Active Directory (AAD) user will get in relation to Dynamics 365 Finance & Operations environment\n        \n    .PARAMETER SignInName\n        The sign in name (email address) for the user that you want the SID from\n        \n    .PARAMETER Provider\n        The provider connected to the sign in name\n        \n    .EXAMPLE\n        PS C:\\> Get-UserSIDFromAad -SignInName \"Claire@contoso.com\" -Provider \"ZXY\"\n        \n        This will get the SID for Azure Active Directory user \"Claire@contoso.com\"\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-UserSIDFromAad {\n    [CmdletBinding()]\n    [OutputType('System.String')]\n    param     (\n        [string] $SignInName,\n        \n        [string] $Provider\n    )\n\n    try {\n\n        $productDetails = Get-ProductInfoProvider\n\n        Add-Type -Path \"$Script:AOSPath\\bin\\Microsoft.Dynamics.BusinessPlatform.SharedTypes.dll\"\n        Add-Type -Path \"$Script:AOSPath\\bin\\Microsoft.Dynamics.ApplicationPlatform.PerformanceCounters.dll\"\n        Add-Type -Path \"$Script:AOSPath\\bin\\Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll\"\n        Add-Type -Path \"$Script:AOSPath\\bin\\Microsoft.Dynamics.AX.Security.SidGenerator.dll\"\n\n        if ($([Version]$productDetails.ApplicationVersion) -ge $([Version]\"10.0.13\")) {\n            $SID = [Microsoft.Dynamics.Ax.Security.SidGenerator]::Generate($SignInName, $Provider, [Microsoft.Dynamics.Ax.Security.SidGenerator+SidAlgorithm]::Sha1)\n        }\n        else {\n            $SID = [Microsoft.Dynamics.Ax.Security.SidGenerator]::Generate($SignInName, $Provider)\n        }\n        \n        Write-PSFMessage -Level Verbose -Message \"Generated SID: $SID\" -Target $SID\n\n        $SID\n\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\"\n        return\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/get-windowsdefenderstatus.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get Windows Defender Status\n        \n    .DESCRIPTION\n        Will get the current status of the Windows Defender\n        \n    .PARAMETER Silent\n        Instruct the cmdlet to silence the output written to the console\n        \n        If set the output will be silenced, if not set, the output will be written to the console\n        \n    .EXAMPLE\n        PS C:\\> Get-WindowsDefenderStatus\n        \n        This will get the status of Windows Defender.\n        It will write the output to the console.\n        \n    .EXAMPLE\n        PS C:\\> Get-WindowsDefenderStatus -Silent\n        \n        This will get the status of Windows Defender.\n        All outputs will be silenced.\n        \n    .NOTES\n        Inspired by https://gallery.technet.microsoft.com/scriptcenter/PowerShell-to-Check-if-811b83bc\n        \n        Author: Robin Kretzschmar (@darksmile92)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Get-WindowsDefenderStatus {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    [OutputType('System.Boolean')]\n    param (\n        [switch] $Silent\n    )\n    try {\n        $defenderOptions = Get-MpComputerStatus\n     \n        if ([string]::IsNullOrEmpty($defenderOptions)) {\n            if ($Silent -eq $false) {\n                Write-PSFMessage -Level Host -Message \"Windows Defender was not found running on the Server: $($env:computername)\"\n            }\n\n            $false\n        }\n        else {\n            if ($Silent -eq $false) {\n                Write-PSFHostColor -DefaultColor \"Cyan\" -String \"Windows Defender was found on the Server: $($env:computername)\"\n                Write-PSFHostColor -DefaultColor \"Yellow\" -String \"   Is Windows Defender Enabled? $($defenderOptions.AntivirusEnabled)\"\n                Write-PSFHostColor -DefaultColor \"Yellow\" -String \"   Is Windows Defender Service Enabled? $($defenderOptions.AMServiceEnabled)\"\n                Write-PSFHostColor -DefaultColor \"Yellow\" -String \"   Is Windows Defender Antispyware Enabled? $($defenderOptions.AntispywareEnabled)\"\n                Write-PSFHostColor -DefaultColor \"Yellow\" -String \"   Is Windows Defender OnAccessProtection Enabled? $($defenderOptions.OnAccessProtectionEnabled)\"\n                Write-PSFHostColor -DefaultColor \"Yellow\" -String \"   Is Windows Defender RealTimeProtection Enabled? $($defenderOptions.RealTimeProtectionEnabled)\"\n            }\n            if ($defenderOptions.AntivirusEnabled -eq $true) {\n                $true\n            }\n            else {\n                $false\n            }\n        }\n    }\n    catch {\n        if ($Silent -eq $false) {\n            Write-PSFMessage -Level Host -Message \"Windows Defender was not found running on the Server: $($env:computername)\"\n        }\n\n        $false\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/import-aadapplicationIntod365fo.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Import an Azure Active Directory (AAD) application\n        \n    .DESCRIPTION\n        Import an Azure Active Directory (AAD) application into a Dynamics 365 for Finance & Operations environment\n        \n    .PARAMETER SqlCommand\n        The SQL Command object that should be used when importing the AAD application\n        \n    .PARAMETER Name\n        The name that the imported application should have inside the D365FO environment\n        \n    .PARAMETER UserId\n        The id of the user linked to the application inside the D365FO environment\n        \n    .PARAMETER ClientId\n        The Client ID that the imported application should use inside the D365FO environment\n        \n    .EXAMPLE\n        PS C:\\> $SqlCommand = Get-SqlCommand -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\"\n        PS C:\\> Import-AadApplicationIntoD365FO -SqlCommand $SqlCommand -Name \"Application1\" -UserId \"admin\" -ClientId \"aef2e67c-64a3-4c72-9294-d288c5bf503d\"\n        This will get a SqlCommand object that will connect to the localhost server and the AXDB database, with the sql credential \"User123\".\n        The SqlCommand object is passed to the Import-AadApplicationIntoD365FO along with all the necessary details for importing Application1 as an application linked to user admin into the D365FO environment.\n        \n    .NOTES\n        Author: Gert Van Der Heyden (@gertvdheyden)\n        \n#>\nfunction Import-AadApplicationIntoD365FO {\n    [CmdletBinding()]\n    param\n    (\n        [System.Data.SqlClient.SqlCommand] $SqlCommand,\n\n        [string] $Name,\n\n        [string] $UserId,\n\n        [string] $ClientId\n    )\n\n    Write-PSFMessage -Level Verbose -Message \"Testing the userid $UserId\"\n\n    $idExists = Test-AadUserIdInD365FO $sqlCommand $UserId\n\n    if ($idExists -eq $true) {\n\n        New-D365FOAadApplication $sqlCommand $Name $UserId $ClientId\n\n        Write-PSFMessage -Level Host -Message \"Application $Name for user $UserId added to D365FO\"\n    }\n    else {\n        Write-PSFMessage -Level Host -Message \"An User with ID = '$UserId' does not exists\"\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/import-aaduserIntod365fo.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Import an Azure Active Directory (AAD) user\n        \n    .DESCRIPTION\n        Import an Azure Active Directory (AAD) user into a Dynamics 365 for Finance & Operations environment\n        \n    .PARAMETER SqlCommand\n        The SQL Command object that should be used when importing the AAD user\n        \n    .PARAMETER SignInName\n        The sign in name (email address) for the user that you want to import\n        \n    .PARAMETER Name\n        The name that the imported user should have inside the D365FO environment\n        \n    .PARAMETER Id\n        The ID that the imported user should have inside the D365FO environment\n        \n    .PARAMETER SID\n        The SID that correlates to the imported user inside the D365FO environment\n        \n    .PARAMETER StartUpCompany\n        The default company (legal entity) for the imported user\n        \n    .PARAMETER IdentityProvider\n        The provider for the imported to validated against\n        \n    .PARAMETER NetworkDomain\n        The network domain of the imported user\n        \n    .PARAMETER ObjectId\n        The Azure Active Directory object id for the imported user\n        \n    .PARAMETER Language\n        Language that should be configured for the user, for when they sign-in to the D365 environment\n        \n    .EXAMPLE\n        PS C:\\> $SqlCommand = Get-SqlCommand -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\"\n        PS C:\\> Import-AadUserIntoD365FO -SqlCommand $SqlCommand -SignInName \"Claire@contoso.com\" -Name \"Claire\" -Id \"claire\" -SID \"123XYZ\" -StartupCompany \"DAT\" -IdentityProvider \"XYZ\" -NetworkDomain \"Contoso.com\" -ObjectId \"123XYZ\"\n        This will get a SqlCommand object that will connect to the localhost server and the AXDB database, with the sql credential \"User123\".\n        The SqlCommand object is passed to the Import-AadUserIntoD365FO along with all the necessary details for importing Claire@contoso.com as an user into the D365FO environment.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Import-AadUserIntoD365FO {\n    [CmdletBinding()]\n    param\n    (\n        [System.Data.SqlClient.SqlCommand] $SqlCommand,\n\n        [string] $SignInName,\n\n        [string] $Name,\n\n        [string] $Id,\n\n        [string] $SID,\n\n        [string] $StartUpCompany,\n\n        [string] $IdentityProvider,\n\n        [string] $NetworkDomain,\n\n        [string] $ObjectId,\n\n        [string] $Language\n    )\n\n    Write-PSFMessage -Level Verbose -Message \"Testing the Email $signInName\" -Target $signInName\n\n    $UserFound = Test-AadUserInD365FO $sqlCommand $SignInName\n\n    if ($UserFound -eq $false) {\n\n        Write-PSFMessage -Level Verbose -Message \"Testing the userid $Id\" -Target $Id\n\n        $idTaken = Test-AadUserIdInD365FO $sqlCommand $id\n\n        if (Test-PSFFunctionInterrupt) { return }\n\n        if ($idTaken -eq $false) {\n\n            $userAdded = New-D365FOUser $sqlCommand $SignInName $Name $Id $Sid $StartUpCompany $IdentityProvider $NetworkDomain $ObjectId $Language\n\n            if ($userAdded -eq $true) {\n\n                $securityAdded = Add-AadUserSecurity $sqlCommand $Id\n\n                Write-PSFMessage -Level Host -Message \"User $SignInName Imported\"\n\n                if ($securityAdded -eq $false) {\n                    Write-PSFMessage -Level Host -Message \"User $SignInName did not get securityRoles\"\n                    #Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n                    #return\n                }\n            }\n            else {\n                Write-PSFMessage -Level Host -Message \"User $SignInName, not added to D365FO\"\n                #Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n                #return\n            }\n        }\n        else {\n            Write-PSFMessage -Level Host -Message \"An User with ID = '$ID' already exists\"\n            #Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            #return\n        }\n\n    }\n    else {\n        Write-PSFMessage -Level Host -Message \"An User with Email $SignInName already exists in D365FO\"\n        #Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n        #return\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/import-assemblyfileintomemory.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Imports a .NET dll file into memory\n        \n    .DESCRIPTION\n        Imports a .NET dll file into memory, by creating a copy (temporary file) and imports it using reflection\n        \n    .PARAMETER Path\n        Path to the dll file you want to import\n        \n        Accepts an array of strings\n        \n    .PARAMETER UseTempFolder\n        Instruct the cmdlet to create the file copy in the default temp folder\n        \n        This switch can be used, if writing to the original folder is not wanted or not possible\n        \n    .EXAMPLE\n        PS C:\\> Import-AssemblyFileIntoMemory -Path \"C:\\AOSService\\PackagesLocalDirectory\\Bin\\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Framework.dll\"\n        \n        This will create an new file named \"C:\\AOSService\\PackagesLocalDirectory\\Bin\\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Framework.dll_shawdow.dll\"\n        The new file is then imported into memory using .NET Reflection.\n        After the file has been imported, it will be deleted from disk.\n        \n    .EXAMPLE\n        PS C:\\> Import-AssemblyFileIntoMemory -Path \"C:\\AOSService\\PackagesLocalDirectory\\Bin\\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Framework.dll\" -UseTempFolder\n        \n        This will create an new file named \"Microsoft.Dynamics.BusinessPlatform.ProductInformation.Framework.dll_shawdow.dll\" in the temp folder\n        The new file is then imported into memory using .NET Reflection.\n        After the file has been imported, it will be deleted from disk.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Import-AssemblyFileIntoMemory {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [Parameter(Mandatory = $true, Position = 1)]\n        [string[]] $Path,\n\n        [switch] $UseTempFolder\n    )\n\n    if (-not (Test-PathExists -Path $Path -Type Leaf)) {\n        Stop-PSFFunction -Message \"Stopping because unable to locate file.\" -StepsUpward 1\n        return\n    }\n\n    foreach ($itemPath in $Path) {\n\n        if ($UseTempFolder) {\n            $filename = Split-Path -Path $itemPath -Leaf\n            $shadowClonePath = Join-Path $env:TEMP \"$filename`_shadow.dll\"\n        }\n        else {\n            $shadowClonePath = \"$itemPath`_shadow.dll\"\n        }\n\n        try {\n            Write-PSFMessage -Level Debug -Message \"Cloning $itemPath to $shadowClonePath\"\n            Copy-Item -Path $itemPath -Destination $shadowClonePath -Force\n    \n            Write-PSFMessage -Level Debug -Message \"Loading $shadowClonePath into memory\"\n            $null = [AppDomain]::CurrentDomain.Load(([System.IO.File]::ReadAllBytes($shadowClonePath)))\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\"\n            return\n        }\n        finally {\n            Write-PSFMessage -Level Debug -Message \"Removing $shadowClonePath\"\n            Remove-Item -Path $shadowClonePath -Force -ErrorAction SilentlyContinue\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/import-generatereportassemblies.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Import assemblies needed for the metat report generation\n        \n    .DESCRIPTION\n        Import all assemblies that are needed to work with the meta data provider for all related objects\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\\bin\n        \n    .EXAMPLE\n        PS C:\\> Import-GenerateReportAssemblies\n        \n        This will import all needed assemblies into memory.\n        \n    .NOTES\n        Tags: Metadata, Report, Documentation\n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Import-GenerateReportAssemblies {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    param (\n        [string] $BinDir = \"$Script:BinDir\\bin\"\n    )\n    \n    end {\n        $Files2Process = New-Object System.Collections.Generic.List[string]\n        \n        $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Management.Delta.dll\"))\n        $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Management.Diff.dll\"))\n        $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Management.Merge.dll\"))\n        $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Management.Core.dll\"))\n        $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.dll\"))\n        $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Core.dll\"))\n        $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Storage.dll\"))\n        $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll\"))\n        $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Metadata.Extensions.dll\"))\n        $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Server.Core.dll\"))\n        $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Xpp.AxShared.dll\"))\n        $Files2Process.Add((Join-Path $BinDir \"Microsoft.Dynamics.AX.Xpp.Support.dll\"))\n\n        Import-AssemblyFileIntoMemory -Path $($Files2Process.ToArray())\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/invoke-azurebackuprestore.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Create a database copy in Azure SQL Database instance\n        \n    .DESCRIPTION\n        Create a new database by cloning a database in Azure SQL Database instance\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER NewDatabaseName\n        Name of the new / cloned database in the Azure SQL Database instance\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-AzureBackupRestore -DatabaseServer TestServer.database.windows.net -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\" -NewDatabaseName ExportClone\n        \n        This will create a database named \"ExportClone\" in the \"TestServer.database.windows.net\" Azure SQL Database instance.\n        It uses the SQL credential \"User123\" to preform the needed actions.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nFunction Invoke-AzureBackupRestore {\n    [CmdletBinding()]\n    [OutputType('System.Boolean')]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseServer,\n\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseName,\n\n        [Parameter(Mandatory = $true)]\n        [string] $SqlUser,\n\n        [Parameter(Mandatory = $true)]\n        [string] $SqlPwd,\n\n        [Parameter(Mandatory = $true)]\n        [string] $NewDatabaseName,\n\n        [switch] $EnableException\n    )\n\n    Invoke-TimeSignal -Start\n\n    $StartTime = Get-Date\n    \n    $SqlConParams = @{DatabaseServer = $DatabaseServer; SqlUser = $SqlUser; SqlPwd = $SqlPwd; TrustedConnection = $false}\n    $sqlCommand = Get-SqlCommand @SqlConParams -DatabaseName $DatabaseName\n    \n    $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\newazuredbfromcopy.sql\") -join [Environment]::NewLine\n    \n    $commandText = $commandText.Replace('@CurrentDatabase', $DatabaseName)\n    $commandText = $commandText.Replace('@NewName', $NewDatabaseName)\n\n    $sqlCommand.CommandText = $commandText\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n        Write-PSFMessage -Level Verbose -Message \"Starting the cloning process of the Azure DB.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n        \n        $null = $sqlCommand.ExecuteNonQuery()\n    }\n    catch {\n        $messageString = \"Something went wrong while <c='em'>cloning</c> the Azure DB database.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand)\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ -StepsUpward 1\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n    }\n   \n    $sqlCommand = Get-SqlCommand @SqlConParams -DatabaseName \"master\"\n\n    $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\checkfornewazuredb.sql\") -join [Environment]::NewLine\n\n    $sqlCommand.CommandText = $commandText\n\n    $null = $sqlCommand.Parameters.Add(\"@NewName\", $NewDatabaseName)\n    $null = $sqlCommand.Parameters.Add(\"@Time\", $StartTime)\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n        Write-PSFMessage -Level Verbose -Message \"Start to wait for the cloning process of the Azure DB to complete.\"\n\n        $sqlCommand.Connection.Open()\n\n        $operation_row_count = 0\n        #Loop every minute until we get a row, if we get a row copy is done\n        while ($operation_row_count -eq 0) {\n            $Reader = $sqlCommand.ExecuteReader()\n            $Datatable = New-Object System.Data.DataTable\n            $Datatable.Load($Reader)\n            $operation_row_count = $Datatable.Rows.Count\n            $time = (Get-Date).ToString(\"HH:mm:ss\")\n            Write-PSFMessage -Level Verbose -Message \"Cloning not complete Sleeping for 60 seconds. [$time]\"\n            Start-Sleep -s 60\n        }\n\n        $true\n    }\n    catch {\n        $messageString = \"Something went wrong while <c='em'>waiting</c> for the clone process of the Azure DB database to complete.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand)\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ -StepsUpward 1\n        return\n    }\n    finally {\n        $Reader.close()\n\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n        $Datatable.Dispose()\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/invoke-clearazurespecificobjects.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Clear Azure SQL Database specific objects\n        \n    .DESCRIPTION\n        Clears all the objects that can only exists inside an Azure SQL Database instance or disable things that will require rebuilding on the receiving system\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-ClearAzureSpecificObjects -DatabaseServer TestServer.database.windows.net -DatabaseName ExportClone -SqlUser User123 -SqlPwd \"Password123\"\n        \n        This will execute all necessary scripts against the \"ExportClone\" database that exists in the \"TestServer.database.windows.net\" Azure SQL Database instance.\n        It uses the SQL credential \"User123\" to preform the needed actions.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nFunction Invoke-ClearAzureSpecificObjects {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    [OutputType([System.Boolean])]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseServer,\n\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseName,\n\n        [Parameter(Mandatory = $true)]\n        [string] $SqlUser,\n\n        [Parameter(Mandatory = $true)]\n        [string] $SqlPwd,\n\n        [switch] $EnableException\n    )\n        \n    $Params = Get-DeepClone $PSBoundParameters\n    if($Params.ContainsKey(\"EnableException\")){$null = $Params.Remove(\"EnableException\")}\n\n    $sqlCommand = Get-SqlCommand @Params -TrustedConnection $false\n\n    $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\clear-azurebacpacdatabase.sql\") -join [Environment]::NewLine\n\n    $commandText = $commandText.Replace(\"@NewDatabase\", $DatabaseName)\n    \n    $sqlCommand.CommandText = $commandText\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n\n        $null = $sqlCommand.ExecuteNonQuery()\n\n        $true\n    }\n    catch {\n        $messageString = \"Something went wrong while <c='em'>clearing</c> the <c='em'>Azure</c> specific objects in the database.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand)\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ -StepsUpward 1\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/invoke-clearsqlspecificobjects.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Clear SQL Server (on-premises) specific objects\n        \n    .DESCRIPTION\n        Clears all the objects that can only exists inside a SQL Server (on-premises) instance or disable things that will require rebuilding on the receiving system\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER TrustedConnection\n        Should the connection use a Trusted Connection or not\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-ClearSqlSpecificObjects -DatabaseServer localhost -DatabaseName ExportClone -SqlUser User123 -SqlPwd \"Password123\"\n        \n        This will execute all necessary scripts against the \"ExportClone\" database that exists in the localhost SQL Server instance.\n        It uses the SQL credential \"User123\" to preform the needed actions.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nFunction Invoke-ClearSqlSpecificObjects {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    [OutputType([System.Boolean])]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseServer,\n\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseName,\n\n        [Parameter(Mandatory = $false)]\n        [string] $SqlUser,\n\n        [Parameter(Mandatory = $false)]\n        [string] $SqlPwd,\n        \n        [Parameter(Mandatory = $false)]\n        [boolean] $TrustedConnection,\n\n        [switch] $EnableException\n    )\n    \n    $Params = Get-DeepClone $PSBoundParameters\n    if($Params.ContainsKey(\"EnableException\")){$null = $Params.Remove(\"EnableException\")}\n\n    $sqlCommand = Get-SqlCommand @Params\n\n    $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\clear-sqlbacpacdatabase.sql\") -join [Environment]::NewLine\n\n    $sqlCommand.CommandText = $commandText\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n\n        $null = $sqlCommand.ExecuteNonQuery()\n\n        $true\n    }\n    catch {\n        $messageString = \"Something went wrong while <c='em'>clearing</c> the <c='em'>SQL</c> specific objects in the database.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand)\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ -StepsUpward 1\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/invoke-compilerresultanalyzer.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Analyze the compiler output log\n        \n    .DESCRIPTION\n        Analyze the compiler output log and generate an excel file contain worksheets per type: Errors, Warnings, Tasks\n        \n        It could be a Visual Studio compiler log or it could be a Invoke-D365ModuleCompile log you want analyzed\n        \n    .PARAMETER Path\n        Path to the compiler log file that you want to work against\n        \n        A BuildModelResult.log or a Dynamics.AX.*.xppc.log file will both work\n        \n    .PARAMETER Identifier\n        Identifier used to name the error output when hitting parsing errors\n        \n    .PARAMETER OutputPath\n        Path where you want the excel file (xlsx-file) saved to\n        \n    .PARAMETER SkipWarnings\n        Instructs the cmdlet to skip warnings while analyzing the compiler output log file\n        \n    .PARAMETER SkipTasks\n        Instructs the cmdlet to skip tasks while analyzing the compiler output log file\n        \n    .PARAMETER PackageDirectory\n        Path to the directory containing the installed package / module\n        \n    .EXAMPLE\n        PS C:\\> Invoke-CompilerResultAnalyzer -Path \"c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log\" -Identifier \"Custom\" -OutputPath \"C:\\Temp\\d365fo.tools\\custom-CompilerResults.xslx\" -PackageDirectory \"J:\\AOSService\\PackagesLocalDirectory\"\n        \n        This will analyze the compiler log file and generate a compiler result excel file.\n        \n    .NOTES\n        Tags: Compiler, Build, Errors, Warnings, Tasks\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n        This cmdlet is inspired by the work of \"Vilmos Kintera\" (twitter: @DAXRunBase)\n        \n        All credits goes to him for showing how to extract these information\n        \n        His blog can be found here:\n        https://www.daxrunbase.com/blog/\n        \n        The specific blog post that we based this cmdlet on can be found here:\n        https://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/\n        \n        The github repository containing the original scrips can be found here:\n        https://github.com/DAXRunBase/PowerShell-and-Azure\n#>\nfunction Invoke-CompilerResultAnalyzer {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidAssignmentToAutomaticVariable\", \"\")]\n    [CmdletBinding()]\n    [OutputType('')]\n    param (\n        [string] $Path,\n\n        [string] $Identifier,\n\n        [string] $OutputPath,\n\n        [switch] $SkipWarnings,\n\n        [switch] $SkipTasks,\n\n        [string] $PackageDirectory\n    )\n\n    Invoke-TimeSignal -Start\n\n    if (-not (Test-PathExists -Path $PackageDirectory -Type Container)) { return }\n\n    $positionRegex = '(?=\\[\\().*(?=\\)\\])'\n    $positionSplitRegex = '(.*)(?=\\[\\().*(?:\\)\\]: )(.*)'\n\n    $warningRegex = '(?:Compile Fatal|MetadataProvider|Metadata|Compile|Unspecified|Generation|ExternalReference|BestPractices) (Warning): (Query Method|Interface Method|Form Method LocalFunction|Form Control Method|Form Datasource Method|Form DataSource Method|Form DataSource DataField Method|Form Method|Map Method|Class Delegate|Table Method LocalFunction|Class Method LocalFunction|Table Method|Class Method|Table|Class|View|Form|)(?: |)(?:dynamics:|)(.*)(?:: )(.*)'\n    $taskRegex = '(TaskListItem Information): (Query Method|Interface Method|Form Method LocalFunction|Form Control Method|Form Datasource Method|Form DataSource Method|Form DataSource DataField Method|Form Method|Map Method|Class Delegate|Table Method LocalFunction|Class Method LocalFunction|Table Method|Class Method|Table|Class|View|Form|)(?: |)(?:dynamics:|)(.*)(?:: )(.*)'\n    $errorRegex = '(?:Compile Fatal|MetadataProvider|Metadata|Compile|Unspecified|Generation) (Error): (Query Method|Interface Method|Form Method LocalFunction|Form Control Method|Form Datasource Method|Form DataSource Method|Form DataSource DataField Method|Form Method|Map Method|Class Delegate|Table Method LocalFunction|Class Method LocalFunction|Table Method|Class Method|Table|Class|View|Form|)(?: |)(?:dynamics:|)(.*)(?:: )(.*)'\n\n    $warningObjects = New-Object System.Collections.Generic.List[System.Object]\n    $errorObjects = New-Object System.Collections.Generic.List[System.Object]\n    $taskObjects = New-Object System.Collections.Generic.List[System.Object]\n    \n    if (-not $SkipWarnings) {\n        Write-PSFMessage -Level Verbose -Message \"Will analyze for warnings in the log file.\" -Target $SkipWarnings\n\n        try {\n            $warningText = Select-String -LiteralPath $Path -Pattern '(^.*) Warning: (.*)' | ForEach-Object { $_.Line }\n            \n            # Skip modules that do not have warnings\n            if ($warningText) {\n                Write-PSFMessage -Level Verbose -Message \"Found warning lines in the log file.\"\n\n                foreach ($line in $warningText) {\n                    $lineLocal = $line\n                        \n                    # Remove positioning text in the format of \"[(5,5),(5,39)]: \" for methods\n                    if ($lineLocal -match $positionRegex) {\n                        Write-PSFMessage -Level Verbose -Message \"Position notation was found in the warning line. Will remove it.\"\n\n                        $lineReplaced = [regex]::Split($lineLocal, $positionSplitRegex)\n                        $lineLocal = $lineReplaced[1] + $lineReplaced[2]\n                    }\n    \n                    try {\n                        Write-PSFMessage -Level Verbose -Message \"Will split the warning line, and create result object.\"\n                        # Regular expression matching to split line details into groups\n                        $Matches = [regex]::split($lineLocal, $warningRegex)\n                        $object = [PSCustomObject]@{\n                            OutputType = $Matches[1].trim()\n                            ObjectType = $Matches[2].trim()\n                            Path       = $Matches[3].trim()\n                            Text       = $Matches[4].trim()\n                        }\n\n                        $warningObjects.Add($object)\n                    }\n                    catch {\n                        Write-PSFHostColor -Level Host \"<c='Yellow'>($Identifier) Error during processing line for warnings <</c><c='Red'>$line</c><c='Yellow'>></c>\"\n                    }\n                }\n            }\n        }\n        catch {\n            Write-PSFMessage -Level Host \"Error while processing warnings\"\n        }\n    }\n\n    if (-not $SkipTasks) {\n        Write-PSFMessage -Level Verbose -Message \"Will analyze for tasks in the log file.\" -Target $SkipTasks\n\n        try {\n            $taskText = Select-String -LiteralPath $Path -Pattern '(^.*)TaskListItem Information: (.*)' | ForEach-Object { $_.Line }\n\n            # Skip modules that do not have tasks\n            if ($taskText) {\n                Write-PSFMessage -Level Verbose -Message \"Found task lines in the log file.\"\n\n                foreach ($line in $taskText) {\n                    $lineLocal = $line\n                        \n                    # Remove positioning text in the format of \"[(5,5),(5,39)]: \" for methods\n                    if ($lineLocal -match $positionRegex) {\n                        Write-PSFMessage -Level Verbose -Message \"Position notation was found in the task line. Will remove it.\"\n\n                        $lineReplaced = [regex]::Split($lineLocal, $positionSplitRegex)\n                        $lineLocal = $lineReplaced[1] + $lineReplaced[2]\n                    }\n\n                    # Remove TODO part\n                    if ($lineLocal -match '(?:TODO :|TODO:|TODO)') {\n                        Write-PSFMessage -Level Verbose -Message \"TODO prefix string value was found in the line. Will remove it.\"\n\n                        $lineReplaced = [regex]::Split($lineLocal, '(.*)(?:TODO :|TODO:|TODO)(.*)', [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)\n                        $lineLocal = $lineReplaced[1] + $lineReplaced[2]\n                    }\n\n                    try {\n                        Write-PSFMessage -Level Verbose -Message \"Will split the task line, and create result object.\"\n\n                        # Regular expression matching to split line details into groups\n                        $Matches = [regex]::split($lineLocal, $taskRegex)\n                        $object = [PSCustomObject]@{\n                            OutputType = $Matches[1].trim()\n                            ObjectType = $Matches[2].trim()\n                            Path       = $Matches[3].trim()\n                            Text       = $Matches[4].trim()\n                        }\n\n                        $taskObjects.Add($object)\n                    }\n                    catch {\n                        Write-PSFHostColor -Level Host \"<c='Yellow'>($Identifier) Error during processing line for tasks <</c><c='Red'>$line</c><c='Yellow'>></c>\"\n                    }\n                }\n            }\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Error during processing tasks\"\n        }\n    }\n\n    try {\n        $errorText = Select-String -LiteralPath $Path -Pattern '(^.*) Error: (.*)' | ForEach-Object { $_.Line }\n\n        # Skip modules that do not have errors\n        if ($errorText) {\n            foreach ($line in $errorText) {\n                $lineLocal = $line\n\n                # Remove positioning text in the format of \"[(5,5),(5,39)]: \" for methods\n                if ($lineLocal -match $positionRegex) {\n                    Write-PSFMessage -Level Verbose -Message \"Position notation was found in the error line. Will remove it.\"\n\n                    $lineReplaced = [regex]::Split($lineLocal, $positionSplitRegex)\n                    $lineLocal = $lineReplaced[1] + $lineReplaced[2]\n                }\n\n                try {\n                    Write-PSFMessage -Level Verbose -Message \"Will split the error line, and create result object.\"\n\n                    # Regular expression matching to split line details into groups\n                    $Matches = [regex]::split($lineLocal, $errorRegex)\n                    $object = [PSCustomObject]@{\n                        ErrorType  = $Matches[1].trim()\n                        ObjectType = $Matches[2].trim()\n                        Path       = $Matches[3].trim()\n                        Text       = $Matches[4].trim()\n                    }\n\n                    $errorObjects.Add($object)\n                }\n                catch {\n                    Write-PSFHostColor -Level Host \"<c='Yellow'>($Identifier) Error during processing line for errors <</c><c='Red'>$line</c><c='Yellow'>></c>\"\n                }\n            }\n        }\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Error during processing errors\"\n    }\n\n    Write-PSFMessage -Level Verbose -Message \"Will start exporting the details to the excel file.\" -Target $OutputPath\n\n    $errorObjects.ToArray() | Export-Excel -Path $OutputPath -WorksheetName \"Errors\" -ClearSheet -AutoFilter -AutoSize -BoldTopRow\n\n    $groupErrorTexts = $errorObjects.ToArray() | Group-Object -Property Text | Sort-Object -Property \"Count\" -Descending | Select-PSFObject Count, \"Name as DistinctErrorText\"\n    $groupErrorTexts | Export-Excel -Path $OutputPath -WorksheetName \"Errors-Summary\" -ClearSheet -AutoFilter -AutoSize -BoldTopRow\n        \n    if (-not $SkipWarnings) {\n        Write-PSFMessage -Level Verbose -Message \"Building the warning details and saving them to the excel file.\" -Target $SkipWarnings\n        \n        $warningObjects.ToArray() | Export-Excel -Path $OutputPath -WorksheetName \"Warnings\" -ClearSheet -AutoFilter -AutoSize -BoldTopRow\n\n        $groupWarningTexts = $warningObjects.ToArray() | Group-Object -Property Text | Sort-Object -Property \"Count\" -Descending | Select-PSFObject Count, \"Name as DistinctWarningText\"\n        $groupWarningTexts | Export-Excel -Path $OutputPath -WorksheetName \"Warnings-Summary\" -ClearSheet -AutoFilter -AutoSize -BoldTopRow\n    }\n    else {\n        Remove-Worksheet -Path $OutputPath -WorksheetName \"Warnings\"\n        Remove-Worksheet -Path $OutputPath -WorksheetName \"Warnings-Summary\"\n    }\n\n    if (-not $SkipTasks) {\n        Write-PSFMessage -Level Verbose -Message \"Building the task details and saving them to the excel file.\" -Target $SkipTasks\n\n        $taskObjects.ToArray() | Export-Excel -Path $OutputPath -WorksheetName \"Tasks\" -ClearSheet -AutoFilter -AutoSize -BoldTopRow\n\n        $groupTaskTexts = $taskObjects.ToArray() | Group-Object -Property Text | Sort-Object -Property \"Count\" -Descending | Select-PSFObject Count, \"Name as DistinctTaskText\"\n        $groupTaskTexts | Export-Excel -Path $OutputPath -WorksheetName \"Tasks-Summary\" -ClearSheet -AutoFilter -AutoSize -BoldTopRow\n    }\n    else {\n        Remove-Worksheet -Path $OutputPath -WorksheetName \"Tasks\"\n        Remove-Worksheet -Path $OutputPath -WorksheetName \"Tasks-Summary\"\n    }\n\n    [PSCustomObject]@{\n        File     = $OutputPath\n        Filename = $(Split-Path -Path $OutputPath -Leaf)\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/invoke-modelutil.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Invoke the ModelUtil.exe\n        \n    .DESCRIPTION\n        A cmdlet that wraps some of the cumbersome work into a streamlined process\n        \n    .PARAMETER Command\n        Instruct the cmdlet to what process you want to execute against the ModelUtil tool\n        \n        Valid options:\n        Import\n        Export\n        Delete\n        Replace\n        \n    .PARAMETER Path\n        Used for import to point where to import from\n        Used for export to point where to export the model to\n        \n        The cmdlet only supports an already extracted \".axmodel\" file\n        \n    .PARAMETER Model\n        Name of the model that you want to work against\n        \n        Used for export to select the model that you want to export\n        Used for delete to select the model that you want to delete\n        \n    .PARAMETER BinDir\n        The path to the bin directory for the environment\n        \n        Default path is the same as the AOS service PackagesLocalDirectory\\bin\n        \n        Default value is fetched from the current configuration on the machine\n        \n    .PARAMETER MetaDataDir\n        The path to the meta data directory for the environment\n        \n        Default path is the same as the aos service PackagesLocalDirectory\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .EXAMPLE\n        PS C:\\> Invoke-ModelUtil -Command Import -Path \"c:\\temp\\d365fo.tools\\CustomModel.axmodel\"\n        \n        This will execute the import functionality of ModelUtil.exe and have it import the \"CustomModel.axmodel\" file.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-ModelUtil -Command Export -Path \"c:\\temp\\d365fo.tools\" -Model CustomModel\n        \n        This will execute the export functionality of ModelUtil.exe and have it export the \"CustomModel\" model.\n        The file will be placed in \"c:\\temp\\d365fo.tools\".\n        \n    .EXAMPLE\n        PS C:\\> Invoke-ModelUtil -Command Delete -Model CustomModel\n        \n        This will execute the delete functionality of ModelUtil.exe and have it delete the \"CustomModel\" model.\n        The folders in PackagesLocalDirectory for the \"CustomModel\" will NOT be deleted\n        \n    .EXAMPLE\n        PS C:\\> Invoke-ModelUtil -Command Replace -Path \"c:\\temp\\d365fo.tools\\CustomModel.axmodel\"\n        \n        This will execute the replace functionality of ModelUtil.exe and have it replace the \"CustomModel\" model.\n        \n    .NOTES\n        Tags: AXModel, Model, ModelUtil, Servicing, Import, Export, Delete, Replace\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Invoke-ModelUtil {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidDefaultValueSwitchParameter\", \"\")]\n    [CmdletBinding(DefaultParameterSetName = 'Default')]\n    \n    param (\n        [Parameter(Mandatory = $true)]\n        [ValidateSet('Import', 'Export', 'Delete', 'Replace')]\n        [string] $Command,\n\n        [Parameter(Mandatory = $True, ParameterSetName = 'Import', Position = 1 )]\n        [Parameter(Mandatory = $True, ParameterSetName = 'Export', Position = 1 )]\n        [Alias('File')]\n        [string] $Path,\n\n        [Parameter(Mandatory = $True, ParameterSetName = 'Export', Position = 2 )]\n        [Parameter(Mandatory = $True, ParameterSetName = 'Delete', Position = 1 )]\n        [string] $Model,\n\n        [string] $BinDir = \"$Script:PackageDirectory\\bin\",\n\n        [string] $MetaDataDir = \"$Script:MetaDataDir\",\n\n        [string] $LogPath,\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly\n    )\n\n    Invoke-TimeSignal -Start\n    \n    if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) {\n        Stop-PSFFunction -Message \"Stopping because of missing paths.\" -StepsUpward 1\n    }\n\n    $executable = Join-Path -Path $BinDir -ChildPath \"ModelUtil.exe\"\n    if (-not (Test-PathExists -Path $executable -Type Leaf)) {\n        Stop-PSFFunction -Message \"Stopping because of missing paths.\" -StepsUpward 1\n    }\n\n    $params = New-Object System.Collections.Generic.List[string]\n\n    Write-PSFMessage -Level Verbose -Message \"Building the parameter options.\"\n    switch ($Command.ToLowerInvariant()) {\n        'import' {\n            if (-not (Test-PathExists -Path $Path -Type Leaf)) {\n                Stop-PSFFunction -Message \"Stopping because of missing paths.\" -StepsUpward 1\n            }\n\n            $params.Add(\"-import\")\n            $params.Add(\"-metadatastorepath=`\"$MetaDataDir`\"\")\n            $params.Add(\"-file=`\"$Path`\"\")\n        }\n        'export' {\n            $params.Add(\"-export\")\n            $params.Add(\"-metadatastorepath=`\"$MetaDataDir`\"\")\n            $params.Add(\"-outputpath=`\"$Path`\"\")\n            $params.Add(\"-modelname=`\"$Model`\"\")\n        }\n        'delete' {\n            $params.Add(\"-delete\")\n            $params.Add(\"-metadatastorepath=`\"$MetaDataDir`\"\")\n            $params.Add(\"-modelname=`\"$Model`\"\")\n        }\n        'replace' {\n            if (-not (Test-PathExists -Path $Path -Type Leaf)) {\n                Stop-PSFFunction -Message \"Stopping because of missing paths.\" -StepsUpward 1\n            }\n\n            $params.Add(\"-replace\")\n            $params.Add(\"-metadatastorepath=`\"$MetaDataDir`\"\")\n            $params.Add(\"-file=`\"$Path`\"\")\n        }\n        \n    }\n\n    Write-PSFMessage -Level Verbose -Message \"Starting the $executable with the parameter options.\" -Target $($params.ToArray() -join \" \")\n    \n    Invoke-Process -Executable $executable -Params $params.ToArray() -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n\n    if (Test-PSFFunctionInterrupt) {\n        Stop-PSFFunction -Message \"Stopping because of 'ModelUtil.exe' failed its execution.\" -StepsUpward 1\n        return\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/invoke-process.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Invoke a process\n        \n    .DESCRIPTION\n        Invoke a process and pass the needed parameters to it\n        \n    .PARAMETER Path\n        Path to the program / executable that you want to start\n        \n    .PARAMETER Params\n        Array of string parameters that you want to pass to the executable\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-Process -Path \"C:\\AOSService\\PackagesLocalDirectory\\Bin\\xppc.exe\" -Params \"-metadata=`\"C:\\AOSService\\PackagesLocalDirectory\\Bin`\"\", \"-modelmodule=`\"ApplicationSuite`\"\", \"-output=`\"C:\\AOSService\\PackagesLocalDirectory\\Bin`\"\", \"-referencefolder=`\"C:\\AOSService\\PackagesLocalDirectory\\Bin`\"\", \"-log=`\"C:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.$Module.xppc.log`\"\", \"-xmlLog=`\"C:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.ApplicationSuite.xppc.xml`\"\", \"-verbose\"\n        \n        This will invoke the \"C:\\AOSService\\PackagesLocalDirectory\\Bin\\xppc.exe\" executable.\n        All parameters will be passed to it.\n        The standard output will be redirected to a local variable.\n        The error output will be redirected to a local variable.\n        The standard output will be written to the verbose stream before exiting.\n        \n        If an error should occur, both the standard output and error output will be written to the console / host.\n        \n    .EXAMPLE\n        PS C:\\> Invoke-Process -ShowOriginalProgress -Path \"C:\\AOSService\\PackagesLocalDirectory\\Bin\\xppc.exe\" -Params \"-metadata=`\"C:\\AOSService\\PackagesLocalDirectory\\Bin`\"\", \"-modelmodule=`\"ApplicationSuite`\"\", \"-output=`\"C:\\AOSService\\PackagesLocalDirectory\\Bin`\"\", \"-referencefolder=`\"C:\\AOSService\\PackagesLocalDirectory\\Bin`\"\", \"-log=`\"C:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.$Module.xppc.log`\"\", \"-xmlLog=`\"C:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.ApplicationSuite.xppc.xml`\"\", \"-verbose\"\n        \n        This will invoke the \"C:\\AOSService\\PackagesLocalDirectory\\Bin\\xppc.exe\" executable.\n        All parameters will be passed to it.\n        The standard output will be outputted directly to the console / host.\n        The error output will be outputted directly to the console / host.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n        https://stackoverflow.com/questions/24370814/how-to-capture-process-output-asynchronously-in-powershell/36539226#36539226\n#>\n\nfunction Invoke-Process {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [Alias('Executable')]\n        [string] $Path,\n\n        [Parameter(Mandatory = $true)]\n        [string[]] $Params,\n\n        [string] $LogPath,\n\n        [switch] $ShowOriginalProgress,\n        \n        [switch] $OutputCommandOnly,\n\n        [switch] $EnableException\n    )\n\n    Invoke-TimeSignal -Start\n\n    if (-not (Test-PathExists -Path $Path -Type Leaf)) { return }\n    \n    if (Test-PSFFunctionInterrupt) { return }\n\n    $tool = Split-Path -Path $Path -Leaf\n\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\n    $pinfo.FileName = \"$Path\"\n    $pinfo.WorkingDirectory = Split-Path -Path $Path -Parent\n\n    if (-not $ShowOriginalProgress) {\n        Write-PSFMessage -Level Verbose \"Output and Error streams will be redirected (silence mode)\"\n\n        $pinfo.RedirectStandardError = $true\n        $pinfo.RedirectStandardOutput = $true\n    }\n\n    $pinfo.UseShellExecute = $false\n    $pinfo.Arguments = \"$($Params -join \" \")\"\n    $p = New-Object System.Diagnostics.Process\n    $p.StartInfo = $pinfo\n\n    Write-PSFMessage -Level Verbose \"Starting the $tool\" -Target \"$($params -join \" \")\"\n\n    if ($OutputCommandOnly) {\n        Write-PSFMessage -Level Host \"$Path $($pinfo.Arguments)\"\n        return\n    }\n    \n    $p.Start() | Out-Null\n    \n    if (-not $ShowOriginalProgress) {\n        $outTask = $p.StandardOutput.ReadToEndAsync();\n        $errTask = $p.StandardError.ReadToEndAsync();\n    }\n\n    Write-PSFMessage -Level Verbose \"Waiting for the $tool to complete\"\n    $p.WaitForExit()\n\n    if (-not $ShowOriginalProgress) {\n        $stdout = $outTask.Result\n        $stderr = $errTask.Result\n    }\n\n    if ($p.ExitCode -ne 0 -and (-not $ShowOriginalProgress)) {\n        Write-PSFMessage -Level Host \"Exit code from $tool indicated an error happened. Will output both standard stream and error stream.\"\n        Write-PSFMessage -Level Host \"Standard output was: \\r\\n $stdout\"\n        Write-PSFMessage -Level Host \"Error output was: \\r\\n $stderr\"\n\n        $messageString = \"Stopping because an Exit Code from $tool wasn't 0 (zero) like expected.\"\n        Stop-PSFFunction -Message \"Stopping because of Exit Code.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -StepsUpward 1\n        return\n    }\n    else {\n        Write-PSFMessage -Level Verbose \"Standard output was: \\r\\n $stdout\"\n    }\n\n    if ((-not $ShowOriginalProgress) -and (-not ([string]::IsNullOrEmpty($LogPath)))) {\n        if (-not (Test-PathExists -Path $LogPath -Type Container -Create)) { return }\n\n        $stdOutputPath = Join-Path -Path $LogPath -ChildPath \"$tool`_StdOutput.log\"\n        $errOutputPath = Join-Path -Path $LogPath -ChildPath \"$tool`_ErrOutput.log\"\n\n        $stdout | Out-File -FilePath $stdOutputPath -Encoding utf8 -Force\n        $stderr | Out-File -FilePath $errOutputPath -Encoding utf8 -Force\n    }\n\n    Invoke-TimeSignal -End\n\n    if (-not $ShowOriginalProgress) {\n        [PSCustomObject]@{\n            stdout = $stdout\n            stderr = $stderr\n            ExitCode = $p.ExitCode\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/invoke-requesthandler.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Invoke the Invoke-RestMethod, wrapped in a handler that helps with the 429 issues\n        \n    .DESCRIPTION\n        A http endpoint will push back on clients, if it feels overwhelmed\n        \n        This translates into 429 in the status code of the http call and requires local logic to respect the retry timeout advice sent back\n        \n    .PARAMETER Method\n        The http method that you want to utilize\n        \n    .PARAMETER Uri\n        The Uri for the endpoint that you want to work against\n        \n    .PARAMETER ContentType\n        The content type value that you want to utilize while working against the endpoint\n        \n    .PARAMETER Payload\n        The payload, if any, that you want to pass to the endpoint\n        \n    .PARAMETER Headers\n        Headers to be used against the endpoint\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .EXAMPLE\n        PS C:\\> Invoke-RequestHandler -Method \"Post\" -Uri 'https://lcsapi.lcs.dynamics.com/environment/v1/stop/project/123456789/environment/d5bbfe74-8b0f-4b5a-afd9-58b19948e5c9' -ContentType \"application/json\" -Headers @{Authorization = \"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOi.....\" }\n        \n        This will post/invoke the stop action for a given environnment in LCS API endpoint.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Invoke-RequestHandler {\n    [CmdletBinding()]\n    param (\n        [Alias(\"HttpMethod\")]\n        [string] $Method,\n\n        [string] $Uri,\n        \n        [string] $ContentType,\n\n        [string] $Payload,\n\n        [Hashtable] $Headers,\n\n        [Timespan] $RetryTimeout = \"00:00:00\"\n    )\n    \n    begin {\n        $parms = @{}\n        $parms.Method = $Method\n        $parms.Uri = $Uri\n        $parms.Headers = $Headers\n        $parms.ContentType = $ContentType\n\n        if ($Payload) {\n            $parms.Body = $Payload\n        }\n\n        $start = (Get-Date)\n        $handleTimeout = $false\n\n        if ($RetryTimeout.Ticks -gt 0) {\n            $handleTimeout = $true\n        }\n    }\n    \n    process {\n        $429Attempts = 0\n\n        do {\n            $429Retry = $false\n\n            try {\n                Invoke-RestMethod @parms\n            }\n            catch [System.Net.WebException] {\n                if ($_.exception.response.statuscode -eq 429) {\n                    $429Retry = $true\n                    \n                    $retryWaitSec = $_.exception.response.Headers[\"Retry-After\"]\n\n                    if (-not ($retryWaitSec -gt 0)) {\n                        $retryWaitSec = 10\n                    }\n\n                    if ($handleTimeout) {\n                        $timeSinceStart = New-TimeSpan -End $(Get-Date) -Start $start\n                        $timeWithWait = $timeSinceStart.Add([timespan]::FromSeconds($retryWaitSec))\n                        \n                        $temp = $RetryTimeout - $timeWithWait\n\n                        if ($temp.Ticks -lt 0) {\n                            #We will be exceeding the timeout limit\n                            $messageString = \"The timeout value suggested from the endpoint will exceed the RetryTimeout (<c='em'>$RetryTimeout</c>) threshold.\"\n                            Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target $entity\n                            Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ -StepsUpward 1\n                            return\n                        }\n                    }\n\n                    Write-PSFMessage -Level Host -Message \"Hit a 429 status code. Will wait for: <c='em'>$retryWaitSec</c> seconds before trying again. Attempt (<c='em'>$429Attempts</c>)\"\n                    Start-Sleep -Seconds $retryWaitSec\n                    $429Attempts++\n                }\n                else {\n                    Throw\n                }\n            }\n        } while ($429Retry)\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/invoke-sqlbackuprestore.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Backup & Restore SQL Server database\n        \n    .DESCRIPTION\n        Backup a database and restore it back into the SQL Server\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER TrustedConnection\n        Should the connection use a Trusted Connection or not\n        \n    .PARAMETER NewDatabaseName\n        Name of the new (restored) database\n        \n    .PARAMETER BackupDirectory\n        Path to a directory that can store the backup file\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Invoke-SqlBackupRestore -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\" -NewDatabaseName \"ExportClone\" -BackupDirectory \"C:\\temp\\d365fo.tools\\sqlbackup\"\n        \n        This will backup the AxDB database and place the backup file inside the \"c:\\temp\\d365fo.tools\\sqlbackup\" directory.\n        The backup file will the be used to restore into a new database named \"ExportClone\".\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nFunction Invoke-SqlBackupRestore {\n    [CmdletBinding()]\n    [OutputType('System.Boolean')]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseServer,\n\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseName,\n\n        [Parameter(Mandatory = $false)]\n        [string] $SqlUser,\n\n        [Parameter(Mandatory = $false)]\n        [string] $SqlPwd,\n        \n        [Parameter(Mandatory = $false)]\n        [boolean] $TrustedConnection,\n\n        [Parameter(Mandatory = $true)]\n        [string] $NewDatabaseName,\n\n        [Parameter(Mandatory = $true)]\n        [string] $BackupDirectory,\n\n        [switch] $EnableException\n    )\n\n    Invoke-TimeSignal -Start\n\n    $Params = @{DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd; TrustedConnection = $TrustedConnection;\n    }\n\n    $sqlCommand = Get-SQLCommand @Params\n\n    $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\backuprestoredb.sql\") -join [Environment]::NewLine\n    $null = $sqlCommand.Parameters.Add(\"@CurrentDatabase\", $DatabaseName)\n    $null = $sqlCommand.Parameters.Add(\"@NewName\", $NewDatabaseName)\n    $null = $sqlCommand.Parameters.Add(\"@BackupDirectory\", $BackupDirectory)\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n        \n        $null = $sqlCommand.ExecuteNonQuery()\n        \n        $true\n    }\n    catch {\n        $messageString = \"Something went wrong while doing <c='em'>backup / restore</c> against the database.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand)\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_\n        return\n    }\n    finally {\n        \n        $sqlCommand.Connection.Close()\n        $sqlCommand.Dispose()\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/invoke-sqlpackage.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Invoke the sqlpackage executable\n        \n    .DESCRIPTION\n        Invoke the sqlpackage executable and pass the necessary parameters to it\n        \n    .PARAMETER Action\n        Can either be import or export\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER TrustedConnection\n        Should the sqlpackage work with TrustedConnection or not\n        \n    .PARAMETER FilePath\n        Path to the file, used for either import or export\n        \n    .PARAMETER Properties\n        Array of all the properties that needs to be parsed to the sqlpackage.exe\n        \n    .PARAMETER DiagnosticFile\n        Path to where you want the SqlPackage to output a diagnostics file to assist you in troubleshooting\n        \n    .PARAMETER ModelFile\n        Path to the model file that you want the SqlPackage.exe to use instead the one being part of the bacpac file\n        \n        This is used to override SQL Server options, like collation and etc\n        \n    .PARAMETER MaxParallelism\n        Sets SqlPackage.exe's degree of parallelism for concurrent operations running against a database\n        \n        The default value is 8\n        \n    .PARAMETER PublishFile\n        Path to the profile / publish xml file that contains all the advanced configuration instructions for the SqlPackage\n        \n        Used only in combination with the Publish action\n        \n    .PARAMETER LogPath\n        The path where the log file(s) will be saved\n        \n    .PARAMETER ShowOriginalProgress\n        Instruct the cmdlet to show the standard output in the console\n        \n        Default is $false which will silence the standard output\n        \n    .PARAMETER OutputCommandOnly\n        Instruct the cmdlet to only output the command that you would have to execute by hand\n        \n        Will include full path to the executable and the needed parameters based on your selection\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> $BaseParams = @{\n        DatabaseServer = $DatabaseServer\n        DatabaseName   = $DatabaseName\n        SqlUser        = $SqlUser\n        SqlPwd         = $SqlPwd\n        }\n        \n        PS C:\\> $ImportParams = @{\n        Action   = \"import\"\n        FilePath = $BacpacFile\n        }\n        \n        PS C:\\> Invoke-SqlPackage @BaseParams @ImportParams\n        \n        This will start the sqlpackage.exe file and pass all the needed parameters.\n        \n    .NOTES\n        Author: Mötz Jensen (@splaxi)\n        \n#>\nfunction Invoke-SqlPackage {\n    [CmdletBinding()]\n    [OutputType([System.Boolean])]\n    param (\n        [ValidateSet(\"Import\", \"Export\", \"Publish\")]\n        [string] $Action,\n\n        [string] $DatabaseServer,\n\n        [string] $DatabaseName,\n\n        [string] $SqlUser,\n\n        [string] $SqlPwd,\n\n        [string] $TrustedConnection,\n\n        [string] $FilePath,\n\n        [string[]] $Properties,\n\n        [string] $DiagnosticFile,\n\n        [string] $ModelFile,\n\n        [int] $MaxParallelism,\n\n        [Alias(\"ProfileFile\")]\n        [string] $PublishFile,\n\n        [string] $LogPath,\n\n        [switch] $ShowOriginalProgress,\n\n        [switch] $OutputCommandOnly,\n\n        [switch] $EnableException\n    )\n\n    $executable = $Script:SqlPackagePath\n\n    Invoke-TimeSignal -Start\n\n    if (!(Test-PathExists -Path $executable -Type Leaf)){\n        try{\n            $envSqlPackage = (Get-Command -Name \"sqlpackage.exe\").Source\n            if (!(Test-PathExists -Path $envSqlPackage -Type Leaf)) { return }\n            else{\n                $executable = $envSqlPackage\n                Set-D365SqlPackagePath -Path $executable\n            }\n        }\n        catch\n        {\n            # SqlPackage.exe is not in $Script:SqlPackagePath\n            # and not in %PATH%, so\n            return\n        }\n    }\n\n    Write-PSFMessage -Level Verbose -Message \"Starting to prepare the parameters for sqlpackage.exe\"\n\n    [System.Collections.ArrayList]$Params = New-Object -TypeName \"System.Collections.ArrayList\"\n\n    if ($Action -eq \"export\") {\n        $null = $Params.Add(\"/Action:export\")\n        $null = $Params.Add(\"/SourceServerName:$DatabaseServer\")\n        $null = $Params.Add(\"/SourceDatabaseName:$DatabaseName\")\n        $null = $Params.Add(\"/SourceTrustServerCertificate:True\")\n        $null = $Params.Add(\"/TargetFile:`\"$FilePath`\"\")\n        $null = $Params.Add(\"/Properties:CommandTimeout=0\")\n\n        if (!$UseTrustedConnection) {\n            $null = $Params.Add(\"/SourceUser:$SqlUser\")\n            $null = $Params.Add(\"/SourcePassword:$SqlPwd\")\n        }\n\n        Remove-Item -Path $FilePath -ErrorAction SilentlyContinue -Force\n    }\n    elseif ($Action -eq \"import\") {\n        $null = $Params.Add(\"/Action:import\")\n        $null = $Params.Add(\"/TargetServerName:$DatabaseServer\")\n        $null = $Params.Add(\"/TargetDatabaseName:$DatabaseName\")\n        $null = $Params.Add(\"/TargetTrustServerCertificate:True\")\n        $null = $Params.Add(\"/SourceFile:`\"$FilePath`\"\")\n        $null = $Params.Add(\"/Properties:CommandTimeout=0\")\n\n        if (!$UseTrustedConnection) {\n            $null = $Params.Add(\"/TargetUser:$SqlUser\")\n            $null = $Params.Add(\"/TargetPassword:$SqlPwd\")\n        }\n    }\n    elseif ($Action -eq \"publish\") {\n        $Params.Add(\"/Action:Publish\") > $null\n        $Params.Add(\"/TargetServerName:$DatabaseServer\") > $null\n        $Params.Add(\"/TargetDatabaseName:$DatabaseName\") > $null\n        $Params.Add(\"/TargetTrustServerCertificate:True\") > $null\n        $Params.Add(\"/SourceFile:`\"$FilePath`\"\") > $null\n        $Params.Add(\"/Properties:CommandTimeout=0\") > $null\n\n        if (-not $UseTrustedConnection) {\n            $Params.Add(\"/TargetUser:$SqlUser\") > $null\n            $Params.Add(\"/TargetPassword:$SqlPwd\") > $null\n        }\n\n        if ($PublishFile) {\n            $Params.Add(\"/Profile:`\"$PublishFile`\"\") > $null\n        }\n    }\n\n    foreach ($item in $Properties) {\n        $Params.Add(\"/Properties:$item\") > $null\n    }\n\n    if ($DiagnosticFile) {\n        $Params.Add(\"/Diagnostics:true\") > $null\n        $Params.Add(\"/DiagnosticsFile:`\"$DiagnosticFile`\"\") > $null\n    }\n\n    if ($ModelFile) {\n        $Params.Add(\"/ModelFilePath:`\"$ModelFile`\"\") > $null\n    }\n\n    if ($MaxParallelism) {\n        $Params.Add(\"/MaxParallelism:$MaxParallelism\") > $null\n    }\n\n    $result = Invoke-Process -Path $executable -Params \"/Version\"\n    $version = $result.stdout -replace \"`r`n\", \"\"\n    Write-PSFMessage -Level Verbose -Message \"Using SQLPackage version $version\"\n\n    Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath\n\n    if (Test-PSFFunctionInterrupt) {\n        Write-PSFMessage -Level Critical -Message \"The SqlPackage.exe exited with an error.\"\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -StepsUpward 1\n        return\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/invoke-timesignal.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Handle time measurement\n        \n    .DESCRIPTION\n        Handle time measurement from when a cmdlet / function starts and ends\n        \n        Will write the output to the verbose stream (Write-PSFMessage -Level Verbose)\n        \n    .PARAMETER Start\n        Switch to instruct the cmdlet that a start time registration needs to take place\n        \n    .PARAMETER End\n        Switch to instruct the cmdlet that a time registration has come to its end and it needs to do the calculation\n        \n    .EXAMPLE\n        PS C:\\> Invoke-TimeSignal -Start\n        \n        This will start the time measurement for any given cmdlet / function\n        \n    .EXAMPLE\n        PS C:\\> Invoke-TimeSignal -End\n        \n        This will end the time measurement for any given cmdlet / function.\n        The output will go into the verbose stream.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Invoke-TimeSignal {\n    [CmdletBinding(DefaultParameterSetName = 'Start')]\n    param (\n        [Parameter(Mandatory = $true, ParameterSetName = 'Start', Position = 1 )]\n        [switch] $Start,\n        \n        [Parameter(Mandatory = $True, ParameterSetName = 'End', Position = 2 )]\n        [switch] $End\n    )\n\n    $Time = (Get-Date)\n\n    $Command = (Get-PSCallStack)[1].Command\n\n    if ($Start) {\n        if ($Script:TimeSignals.ContainsKey($Command)) {\n            Write-PSFMessage -Level Verbose -Message \"The command '$Command' was already taking part in time measurement. The entry has been update with current date and time.\"\n            $Script:TimeSignals[$Command] = $Time\n        }\n        else {\n            $Script:TimeSignals.Add($Command, $Time)\n        }\n    }\n    else {\n        if ($Script:TimeSignals.ContainsKey($Command)) {\n            $TimeSpan = New-TimeSpan -End $Time -Start (($Script:TimeSignals)[$Command])\n\n            Write-PSFMessage -Level Verbose -Message \"Total time spent inside the function was $TimeSpan\" -Target $TimeSpan -FunctionName $Command -Tag \"TimeSignal\"\n            $null = $Script:TimeSignals.Remove($Command)\n        }\n        else {\n            Write-PSFMessage -Level Verbose -Message \"The command '$Command' was never started to take part in time measurement.\"\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/new-d365foaadapplication.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Creates a new Azure Active Directory (AAD) application\n        \n    .DESCRIPTION\n        Creates a new Azure Active Directory (AAD) application in a Dynamics 365 for Finance & Operations instance\n        \n    .PARAMETER sqlCommand\n        The SQL Command object that should be used when creating the new application\n        \n    .PARAMETER Name\n        The name that the imported application should have inside the D365FO environment\n        \n    .PARAMETER UserId\n        The id of the user linked to the application inside the D365FO environment\n        \n    .PARAMETER ClientId\n        The Client ID that the imported application should use inside the D365FO environment\n        \n    .EXAMPLE\n        PS C:\\> $SqlCommand = Get-SqlCommand -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\"\n        PS C:\\> New-D365FOAadApplication -SqlCommand $SqlCommand -Name \"Application1\" -UserId \"admin\" -ClientId \"aef2e67c-64a3-4c72-9294-d288c5bf503d\"\n        This will get a SqlCommand object that will connect to the localhost server and the AXDB database, with the sql credential \"User123\".\n        The SqlCommand object is passed to the New-D365FOAadApplication along with all the necessary details for importing Application1 as an application linked to user admin into the D365FO environment.\n        \n    .NOTES\n        Author: Gert Van Der Heyden (@gertvdheyden)\n        \n#>\nfunction New-D365FOAadApplication {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    Param (\n        [System.Data.SqlClient.SqlCommand] $SqlCommand,\n\n        [string] $Name,\n\n        [string] $UserId,\n\n        [string] $ClientId\n    )\n    \n    $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\Add-AadApplicationIntoD365FO.sql\") -join [Environment]::NewLine\n\n    Write-PSFMessage -Level Verbose -Message \"Adding Application : $Name,$UserId,$ClientId\"\n    \n    $null = $sqlCommand.Parameters.Add(\"@Name\", $Name)\n    $null = $sqlCommand.Parameters.Add(\"@UserId\", $UserId)\n    $null = $sqlCommand.Parameters.Add(\"@ClientId\", $ClientId)\n\n    Write-PSFMessage -Level Verbose -Message \"Creating the application in database\"\n\n    Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n    $null = $sqlCommand.ExecuteNonQuery()\n    \n    Write-PSFMessage -Level Verbose -Message \"Added application\"\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/new-d365fouser.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Creates a new user\n        \n    .DESCRIPTION\n        Creates a new user in a Dynamics 365 for Finance & Operations instance\n        \n    .PARAMETER sqlCommand\n        The SQL Command object that should be used when creating the new user\n        \n    .PARAMETER SignInName\n        The sign in name (email address) for the user that you want the SID from\n        \n    .PARAMETER Name\n        The name that the imported user should have inside the D365FO environment\n        \n    .PARAMETER Id\n        The ID that the imported user should have inside the D365FO environment\n        \n    .PARAMETER SID\n        The SID that correlates to the imported user inside the D365FO environment\n        \n    .PARAMETER StartUpCompany\n        The default company (legal entity) for the imported user\n        \n    .PARAMETER IdentityProvider\n        The provider for the imported to validated against\n        \n    .PARAMETER NetworkDomain\n        The network domain of the imported user\n        \n    .PARAMETER ObjectId\n        The Azure Active Directory object id for the imported user\n        \n    .PARAMETER Language\n        Language that should be configured for the user, for when they sign-in to the D365 environment\n        \n    .EXAMPLE\n        PS C:\\> $SqlCommand = Get-SqlCommand -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\"\n        PS C:\\> New-D365FOUser -SqlCommand $SqlCommand -SignInName \"Claire@contoso.com\" -Name \"Claire\" -Id \"claire\" -SID \"123XYZ\" -StartupCompany \"DAT\" -IdentityProvider \"XYZ\" -NetworkDomain \"Contoso.com\" -ObjectId \"123XYZ\"\n        \n        This will get a SqlCommand object that will connect to the localhost server and the AXDB databae, with the sql credential \"User123\".\n        The SqlCommand object is passed to the Import-AadUserIntoD365FO along with all the necessary details for importing Claire@contoso.com as an user into the D365FO environment.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction New-D365FOUser {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    Param (\n        [System.Data.SqlClient.SqlCommand] $SqlCommand,\n\n        [string] $SignInName,\n        \n        [string] $Name,\n        \n        [string] $Id,\n        \n        [string] $SID,\n        \n        [string] $StartUpCompany,\n        \n        [string] $IdentityProvider,\n        \n        [string] $NetworkDomain,\n        \n        [string] $ObjectId,\n        \n        [string] $Language\n    )\n    \n    $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\Add-AadUserIntoD365FO.sql\") -join [Environment]::NewLine\n\n    Write-PSFMessage -Level Verbose -Message \"Adding User : $SignInName,$Name,$Id,$SID,$StartUpCompany,$IdentityProvider,$NetworkDomain\"\n\n    $null = $sqlCommand.Parameters.Add(\"@SignInName\", $SignInName)\n    $null = $sqlCommand.Parameters.Add(\"@Name\", $Name)\n    $null = $sqlCommand.Parameters.Add(\"@SID\", $SID)\n    $null = $sqlCommand.Parameters.Add(\"@NetworkDomain\", $NetworkDomain)\n    $null = $sqlCommand.Parameters.Add(\"@IdentityProvider\", $IdentityProvider)\n    $null = $sqlCommand.Parameters.Add(\"@StartUpCompany\", $StartUpCompany)\n    $null = $sqlCommand.Parameters.Add(\"@Id\", $Id)\n    $null = $sqlCommand.Parameters.Add(\"@ObjectId\", $ObjectId)\n    $null = $sqlCommand.Parameters.Add(\"@Language\", $Language)\n\n    Write-PSFMessage -Level Verbose -Message \"Creating the user in database\"\n\n    Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n    $rowsCreated = $sqlCommand.ExecuteScalar()\n    \n    Write-PSFMessage -Level Verbose -Message \"Rows inserted $rowsCreated for user $SignInName\"\n    \n    $SqlCommand.Parameters.Clear()\n\n    $rowsCreated -eq 1\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/new-d365selfsignedcertificate.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Create a new self signed certificate\n        \n    .DESCRIPTION\n        Create a new self signed certificate and have it password protected\n        \n    .PARAMETER CertificateFileName\n        Path to the location where you want to store the CER file for the certificate\n        \n    .PARAMETER PrivateKeyFileName\n        Path to the location where you want to store the PFX file for the certificate\n        \n    .PARAMETER Password\n        The password that you want to use to protect your different certificates with\n        \n    .EXAMPLE\n        PS C:\\> New-D365SelfSignedCertificate -CertificateFileName \"C:\\temp\\d365fo.tools\\TestAuth.cer\" -PrivateKeyFileName \"C:\\temp\\d365fo.tools\\TestAuth.pfx\" -Password (ConvertTo-SecureString -String \"pass@word1\" -Force -AsPlainText)\n        \n        This will generate a new CER certificate that is stored at \"C:\\temp\\d365fo.tools\\TestAuth.cer\".\n        This will generate a new PFX certificate that is stored at \"C:\\temp\\d365fo.tools\\TestAuth.pfx\".\n        Both certificates will be password protected with \"pass@word1\".\n        \n    .NOTES\n        Author: Kenny Saelen (@kennysaelen)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction New-D365SelfSignedCertificate {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSAvoidUsingConvertToSecureStringWithPlainText\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $false, Position = 1)]\n        [string] $CertificateFileName = (Join-Path $env:TEMP \"TestAuthCert.cer\"),\n\n        [Parameter(Mandatory = $false, Position = 2)]\n        [string] $PrivateKeyFileName = (Join-Path $env:TEMP \"TestAuthCert.pfx\"),\n\n        [Parameter(Mandatory = $false, Position = 3)]\n        [Security.SecureString] $Password = (ConvertTo-SecureString -String \"Password1\" -Force -AsPlainText)\n    )\n\n    try {\n        # First generate a self-signed certificate and place it in the local store on the machine\n        $certificate = New-SelfSignedCertificate -dnsname 127.0.0.1 -CertStoreLocation cert:\\LocalMachine\\My -FriendlyName \"D365 Automated testing certificate\" -Provider \"Microsoft Strong Cryptographic Provider\"\n        $certificatePath = 'cert:\\localMachine\\my\\' + $certificate.Thumbprint\n\n        # Export the private key\n        Export-PfxCertificate -cert $certificatePath -FilePath $PrivateKeyFileName -Password $Password\n\n        # Import the certificate into the local machine's trusted root certificates store\n        $importedCertificate = Import-PfxCertificate -FilePath $PrivateKeyFileName -CertStoreLocation Cert:\\LocalMachine\\Root -Password $Password\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while generating the self-signed certificate and installing it into the local machine's trusted root certificates store.\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n        return\n    }\n\n    return $importedCertificate\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/new-decryptedfile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Decrypt web.config file\n        \n    .DESCRIPTION\n        Utilize the built in encryptor utility to decrypt the web.config file from inside the AOS\n        \n    .PARAMETER File\n        Path to the file that you want to work against\n        \n        Please be careful not to point to the original file from inside the AOS directory\n        \n    .PARAMETER DropPath\n        Path to the directory where you want save the file after decryption is completed\n        \n    .EXAMPLE\n        PS C:\\> New-DecryptedFile -File \"C:\\temp\\d365fo.tools\\web.config\" -DropPath \"c:\\temp\\d365fo.tools\\decrypted.config\"\n        \n        This will take the \"C:\\temp\\d365fo.tools\\web.config\" and decrypt it.\n        After decryption the output file will be stored in \"c:\\temp\\d365fo.tools\\decrypted.config\".\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction New-DecryptedFile {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    Param (\n        [string] $File,\n        \n        [string] $DropPath\n    )\n    \n    $Decrypter = Join-Path  $AosServiceWebRootPath -ChildPath \"bin\\Microsoft.Dynamics.AX.Framework.ConfigEncryptor.exe\"\n\n    if (-not (Test-PathExists -Path $Decrypter -Type Leaf)) { return }\n\n    $fileInfo = [System.IO.FileInfo]::new($File)\n    $DropFile = Join-Path $DropPath $FileInfo.Name\n    \n    Write-PSFMessage -Level Verbose -Message \"Extracted file path is: $DropFile\" -Target $DropFile\n    Copy-Item $File $DropFile -Force -ErrorAction Stop\n\n    if (-not (Test-PathExists -Path $DropFile -Type Leaf)) { return }\n    \n    & $Decrypter -decrypt $DropFile\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/new-webrequest.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Get a web request object\n        \n    .DESCRIPTION\n        Get a prepared web request object with all necessary headers and tokens in place\n        \n    .PARAMETER RequestUrl\n        The URL you want to work against\n        \n    .PARAMETER AuthorizationHeader\n        The Authorization Header object that you want to use for you web request\n        \n    .PARAMETER Action\n        The HTTP action you want to preform\n        \n    .EXAMPLE\n        PS C:\\> New-WebRequest -RequestUrl \"https://login.windows.net/contoso/.well-known/openid-configuration\" -AuthorizationHeader $null -Action GET\n        \n        This will create a new web request object that will work against the \"https://login.windows.net/contoso/.well-known/openid-configuration\" URL.\n        The HTTP action is GET and in this case we don't need an Authorization Header in place.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction New-WebRequest {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n\n    param    (\n        $RequestUrl,\n        $AuthorizationHeader,\n        $Action\n    )\n    \n    Write-PSFMessage -Level Verbose -Message \"New Request $RequestUrl, $Action\"\n    $request = [System.Net.WebRequest]::Create($RequestUrl)\n\n    if ($null -ne $AuthorizationHeader) {\n        $request.Headers[\"Authorization\"] = $AuthorizationHeader.CreateAuthorizationHeader()\n    }\n\n    $request.Method = $Action\n    \n    $request\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/publish-d365foresources.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Publish resources\n        \n    .DESCRIPTION\n        Publishes Dynamics 365 for Finance and Operations resources to the publishing directory.\n        \n    .PARAMETER ResourceTypes\n        The types of resources to publish.\n        \n    .PARAMETER PublishingDirectory\n        The directory to publish the resources to. Each resource type will be published to a subdirectory.\n        \n    .PARAMETER PackageDirectory\n        The directory containing the resources.\n        \n    .PARAMETER AosServiceWebRootPath\n        The path to the AOS service web root containing the metadata assemblies to access the resources.\n        \n    .EXAMPLE\n        PS C:\\> Publish-D365FOResources -ResourceTypes Images,Scripts,Styles,Html -PublishingDirectory C:\\temp\\resources\n        \n        This will publish the resources of the types Images, Scripts, Styles, and Html to the directory C:\\temp\\resources.\n        \n    .NOTES\n        Author: Florian Hopfner (@FH-Inway)\n#>\nfunction Publish-D365FOResources {\n    [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', 'Publish-D365FOResources')]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string[]] $ResourceTypes,\n\n        [Parameter(Mandatory = $true)]\n        [string] $PublishingDirectory,\n\n        [Parameter(Mandatory = $false)]\n        [PsfDirectory] $PackageDirectory = $Script:PackageDirectory,\n\n        [Parameter(Mandatory = $false)]\n        [PsfDirectory] $AosServiceWebRootPath = $Script:AOSPath\n    )\n\n    Invoke-TimeSignal -Start\n\n    Write-PSFMessage -Level Verbose -Message \"Initializing resources publishing.\"\n  \n    $resourcesDirectory = $PublishingDirectory\n    foreach ($resourceType in $ResourceTypes) {\n        $resourceTypeDirectory = Join-Path $resourcesDirectory $resourceType\n        Test-PathExists -Path $resourceTypeDirectory -Type Container -Create | Out-Null\n    }\n\n    Import-Assemblies -AosServiceWebRootPath $AosServiceWebRootPath\n    # For unknown reasons, the provider cannot be initialized in a separate function.\n    # If this is done, $metadataProviderViaRuntime.Resources is null.\n    Write-PSFMessage -Level Debug -Message \"Initializing metadata runtime provider.\"\n    $runtimeProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.Runtime.RuntimeProviderConfiguration -ArgumentList $PackageDirectory\n    $metadataProviderFactoryViaRuntime = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory\n    $metadataProviderViaRuntime = $metadataProviderFactoryViaRuntime.CreateRuntimeProvider($runtimeProviderConfiguration)\n    \n    Write-PSFMessage -Level Verbose -Message \"Starting resources publishing\"\n    $resources = $metadataProviderViaRuntime.Resources.GetPrimaryKeys()\n    foreach ($resourceItem in $resources) {\n        $params = @{\n            ResourceItem = $resourceItem\n            MetadataProviderViaRuntime = $metadataProviderViaRuntime\n            ResourceTypes = $ResourceTypes\n            ResourcesDirectory = $resourcesDirectory\n        }\n        Publish-Resource @params\n    }\n    Write-PSFMessage -Level Host -Message \"Resources publishing completed.\"\n\n    Invoke-TimeSignal -End\n}\n\nfunction Import-Assemblies {\n    [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', 'Import-Assemblies')]\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [PsfDirectory] $AosServiceWebRootPath\n    )\n\n    Write-PSFMessage -Level Debug -Message \"Importing required assemblies.\"\n    [System.Collections.ArrayList] $Files2Process = New-Object -TypeName \"System.Collections.ArrayList\"\n    $binDir = Join-Path $AosServiceWebRootPath \"bin\"\n    $null = $Files2Process.Add((Join-Path $binDir Microsoft.Dynamics.AX.Metadata.Core.dll))\n    $null = $Files2Process.Add((Join-Path $binDir Microsoft.Dynamics.AX.Metadata.dll))\n    $null = $Files2Process.Add((Join-Path $binDir Microsoft.Dynamics.AX.Metadata.Storage.dll))\n    $null = $Files2Process.Add((Join-Path $binDir Microsoft.Dynamics.Performance.Instrumentation.dll))\n    $null = $Files2Process.Add((Join-Path $binDir Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll))\n    Import-AssemblyFileIntoMemory -Path $($Files2Process.ToArray())\n}\n\nfunction Publish-Resource {\n    [CmdletBinding()]\n    param (\n        [Parameter(Mandatory = $true)]\n        [object] $ResourceItem,\n\n        [Parameter(Mandatory = $true)]\n        [object] $MetadataProviderViaRuntime,\n\n        [Parameter(Mandatory = $true)]\n        [string[]] $ResourceTypes,\n\n        [Parameter(Mandatory = $true)]\n        [string] $ResourcesDirectory\n    )\n\n    $resourceName = [System.String]$ResourceItem\n    Write-PSFMessage -Level Debug -Message \"Processing resource '$resourceName'.\"\n    $resourceHeader = New-Object -TypeName Microsoft.Dynamics.AX.Metadata.MetaModel.MetaReadHeader\n    $resource = $MetadataProviderViaRuntime.Resources.Read($resourceName, [ref]$resourceHeader)\n    $resourceTimestamp = $MetadataProviderViaRuntime.Resources.GetContentTimestampUtc($resource, $resourceHeader)\n    $resourceType = $resource.TypeOfResource\n\n    $resourcePath = Join-Path $ResourcesDirectory $resourceType\n    $resourceFilePath = Join-Path $resourcePath $resource.FileName\n    \n    Write-PSFMessage -Level Debug -Message \"Checking resource '$resourceName' of type '$resourceType' for publishing.\"\n    $resourceData = @{\n        ResourceType = $resourceType\n        ResourceName = $resourceName\n        ResourceTimestamp = $resourceTimestamp\n    }\n    $params = @{\n        ResourceData = $resourceData\n        AllowedResourceTypes = $ResourceTypes\n        ResourceFilePath = $resourceFilePath\n    }\n    $shouldPublishResource = Test-PublishResource @params\n    if (-not $shouldPublishResource) {\n        Write-PSFMessage -Level Debug -Message \"Resource '$resourceName' is not being published.\"\n        continue\n    }\n\n    Write-PSFMessage -Level Debug -Message \"Publishing resource '$resourceName' to '$resourceFilePath'.\"\n    $sourceStream = $MetadataProviderViaRuntime.Resources.GetContent($resource, $resourceHeader)\n    if ($sourceStream) {\n        $argumentList = @(\n            $resourceFilePath,\n            [System.IO.FileMode]::Create,\n            [System.IO.FileAccess]::Write\n        )\n        $targetStream = New-Object -TypeName System.IO.FileStream -ArgumentList $argumentList\n        $sourceStream.CopyTo($targetStream)\n\n        $sourceStream.Close()\n        $targetStream.Close()\n        Write-PSFMessage -Level Debug -Message \"Resource '$resourceName' published successfully.\"\n    }\n}\n\nfunction Test-PublishResource {\n    [CmdletBinding()]\n    [OutputType([System.Boolean])]\n    param (\n        [Parameter(Mandatory = $true)]\n        [hashtable] $ResourceData,\n    \n        [Parameter(Mandatory = $true)]\n        [string[]] $AllowedResourceTypes,\n\n        [Parameter(Mandatory = $true)]\n        [string] $ResourceFilePath\n    )\n\n    $resourceType = $ResourceData.ResourceType\n    $resourceName = $ResourceData.ResourceName\n    $resourceTimestamp = $ResourceData.ResourceTimestamp\n\n    $isAResourceTypeToPublish = $AllowedResourceTypes -contains $resourceType\n    if (-not $isAResourceTypeToPublish) {\n        Write-PSFMessage -Level Debug -Message \"Resource '$resourceName' of type '$resourceType' is not a resource type to publish. Skipping.\"\n        return $false\n    }\n\n    if (-not (Test-PathExists -Path $ResourceFilePath -Type Leaf -WarningAction SilentlyContinue -ErrorAction SilentlyContinue)) {\n        Write-PSFMessage -Level Debug -Message \"Resource '$resourceName' does not exist. Will be published.\"\n        return $true\n    }\n\n    $existingFileTimestamp = (Get-ItemProperty $resourceFilePath).LastWriteTimeUtc\n    if ($existingFileTimestamp -ne $ResourceTimestamp) {\n        Write-PSFMessage -Level Debug -Message \"Resource '$ResourceName' is outdated (resource time stamp: $ResouceTimestamp, existing file time stamp: $existingFileTimestamp). Will be published.\"\n        return $true\n    }\n\n    Write-PSFMessage -Level Debug -Message \"Resource '$ResourceName' is up to date.\"\n    return $false\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/readme.md",
    "content": "﻿# Functions\n\nThis is the folder where the internal functions go.\n\nDepending on the complexity of the module, it is recommended to subdivide them into subfolders.\n\nThe module will pick up all .ps1 files recursively"
  },
  {
    "path": "d365fo.tools/internal/functions/remove-lcsassetfile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Delete a single asset from the LCS project Asset Library\n        \n    .DESCRIPTION\n        Delete a single asset from the LCS project Asset Library\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER AssetId\n        Id of the asset you want to delete\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        Usually this parameter is not used directly, but via the Enable-D365Exception cmdlet\n        See https://github.com/d365collaborative/d365fo.tools/wiki/Exception-handling#what-does-the--enableexception-parameter-do for further information\n        \n    .EXAMPLE\n        Remove-LcsAssetFile -ProjectId 123456789 -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\" -AssetId \"812bcb0e-23fb-476d-8a92-985f20a704b9\"\n        \n        This will delete the Asset file from the LCS Asset Library.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .NOTES\n        Tags: Environment, LCS, Api, AAD, Token, Asset, File, Files\n        \n        Author: Oleksandr Nikolaiev (@onikolaiev)\n#>\nfunction Remove-LcsAssetFile {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Cmdletbinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [int] $ProjectId,\n\n        [Parameter(Mandatory = $true)]\n        [string] $AssetId,\n\n        [Alias('Token')]\n        [string] $BearerToken,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n    begin {\n        Invoke-TimeSignal -Start\n        \n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"POST\"\n        $parms.Uri = \"$LcsApiUri/box/fileasset/DeleteFileAsset/$($ProjectId)?assetId=$($AssetId)\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n    }\n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n            Write-PSFMessage -Level Verbose -Message \"Asset was deleted successfully.\"\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in request for delete asset from the asset library of LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/rename-configvalue.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Rename the value in the web.config file\n        \n    .DESCRIPTION\n        Replace the old value with the new value inside a web.config file\n        \n    .PARAMETER File\n        Path to the file that you want to update/rename/replace\n        \n    .PARAMETER NewValue\n        The new value that replaces the old value\n        \n    .PARAMETER OldValue\n        The old value that needs to be replaced\n        \n    .EXAMPLE\n        PS C:\\> Rename-ConfigValue -File \"C:\\temp\\d365fo.tools\\web.config\" -NewValue \"Demo-8.1\" -OldValue \"usnconeboxax1aos\"\n        \n        This will open the \"C:\\temp\\d365fo.tools\\web.config\" file and replace all \"usnconeboxax1aos\" entries with \"Demo-8.1\"\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Rename-ConfigValue {\n    param (\n        [string] $File,\n        [string] $NewValue,\n        [string] $OldValue\n    )\n\n    Write-PSFMessage -Level Verbose -Message \"Replace content from $File. Old value is $OldValue. New value is $NewValue.\" -Target (@($File, $OldValue, $NewValue))\n    \n    (Get-Content $File).replace($OldValue, $NewValue) | Set-Content $File\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/repair-bacpacmodelqualifier.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Repair a bacpac model file - using qualification logic\n        \n    .DESCRIPTION\n        Will use a search pattern, qualification and end pattern, to remove an element from the model file\n        \n    .PARAMETER Path\n        Path to the bacpac model file that you want to work against\n        \n    .PARAMETER OutputPath\n        Path to where the repaired model file should be placed\n        \n    .PARAMETER Search\n        Search pattern that is used to start the removable of the element\n        \n        Supports wildcard - as it utilizes the -Like operation that is available directly in powershell\n        \n        E.g. \"*<Element Type=\\\"SqlRoleMembership\\\">*\"\n        \n    .PARAMETER Qualifier\n        Qualifier pattern that is used to qualify the element, based on a nested line value\n        \n        Supports wildcard - as it utilizes the -Like operation that is available directly in powershell\n        \n        E.g. \"*<References Name=*ms_db_configwriter*\"\n        \n    .PARAMETER End\n        End pattern that is used to conclude the removable of the element\n        \n        Supports wildcard - as it utilizes the -Like operation that is available directly in powershell\n        \n        E.g. \"*</Element>*\"\n        \n    .EXAMPLE\n        PS C:\\> Repair-BacpacModelQualifier -Path c:\\temp\\model.xml -OutputPath c:\\temp\\repaired_model.xml -Search '*<Element Type=\"SqlRoleMembership\">*' -Qualifier \"*<References Name=*ms_db_configwriter*\" -End \"*</Element>*\"\n        \n        This will remove the below section from the model file\n        \n        <Element Type=\"SqlRoleMembership\">\n        <Relationship Name=\"Member\">\n        <Entry>\n        <References Name=\"[ms_db_configwriter]\" />\n        </Entry>\n        </Relationship>\n        <Relationship Name=\"Role\">\n        <Entry>\n        <References ExternalSource=\"BuiltIns\" Name=\"[db_ddladmin]\" />\n        </Entry>\n        </Relationship>\n        </Element>\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n        Json files has to be an array directly in the root of the file. All \" (double quotes) has to be escaped with \\\" - otherwise it will not work as intended.\n        \n        This cmdlet is inspired by the work of \"Brad Bateman\" (github: @batetech)\n        \n        His github profile can be found here:\n        https://github.com/batetech\n        \n        Florian Hopfner did a gist implementation, which has been used as the foundation for this implementation\n        \n        The original gist is: https://gist.github.com/FH-Inway/f485c720b43b72bffaca5fb6c094707e\n        \n        His github profile can be found here:\n        https://github.com/FH-Inway\n#>\nfunction Repair-BacpacModelQualifier {\n    [CmdletBinding()]\n    param (\n        [string] $Path,\n\n        [string] $OutputPath,\n\n        [string] $Search,\n\n        [string] $Qualifier,\n\n        [string] $End\n        \n    )\n    \n    Invoke-TimeSignal -Start\n    \n    Write-PSFMessage -Level Verbose -Message \"Will search for: $Search - Qualify with: $Qualifier\" -Target @($Search, $Qualifier, $End)\n    \n    [int]$flushCounter = 500000\n\n    $buffer = [System.Collections.Generic.List[string]]::new($flushCounter) #much faster than PS array using +=\n    $bufferCounter = 0;\n    \n    try {\n        $stream = [System.IO.StreamReader]::new($Path)\n\n        :LineLoop while ($stream.Peek() -ge 0) {\n            $line = $stream.ReadLine()\n        \n            # Skipping empty lines\n            if (-not [string]::IsNullOrEmpty($line)) {\n\n                if ($line -like $Search) {\n                    # We hit search pattern, will read lines until hitting the end pattern.\n                    # Will buffer all lines going forward, in case we need to keep them in the output file\n\n                    $bufTemp = [System.Collections.Generic.List[string]]::new(20)\n                    $bufTemp.Add($line)\n                    $foundQualifier = $false\n\n                    while ($stream.Peek() -ge 0) {\n                        $line = $stream.ReadLine();\n                        \n                        $bufTemp.Add($line)\n                    \n                        if ($line -like $Qualifier) {\n                            $foundQualifier = $true\n                        }\n\n                        if ($line -like $End) {\n                            if (-not $foundQualifier) {\n                                # This tells us to keep all the lines that we buffered\n                                $buffer.AddRange($bufTemp.ToArray())\n                            }\n\n                            continue LineLoop\n                        }\n                    }\n                }\n                            \n                # Persisting all lines that didn't meet the search pattern\n                $buffer.Add($line)\n            }\n            else {\n                $buffer.Add($line)\n            }\n\n            $bufferCounter++;\n            if ($bufferCounter -ge $flushCounter) {\n                $buffer | Add-Content -LiteralPath $OutputPath -Encoding UTF8\n                $buffer = [System.Collections.Generic.List[string]]::new($flushCounter);\n                $bufferCounter = 0;\n            }\n        }\n    }\n    finally {\n        # We need to close the stream object, to release the file system lock on the input file\n        $stream.Close()\n        $stream.Dispose()\n    }\n\n    #flush anything still remaining in the buffer\n    if ($bufferCounter -gt 0) {\n        $buffer | Add-Content -LiteralPath $OutputPath -Encoding UTF8\n        $buffer = $null;\n        $bufferCounter = 0;\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/repair-bacpacmodelsimpleandreplace.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Repair a bacpac model file - using simple remove AND replace logic\n        \n    .DESCRIPTION\n        Will use a search pattern, and end pattern, to remove an element from the model file\n        \n        Will use a search pattern, with the replacement value, to replace the string within the model file\n        \n    .PARAMETER Path\n        Path to the bacpac model file that you want to work against\n        \n    .PARAMETER OutputPath\n        Path to where the repaired model file should be placed\n        \n    .PARAMETER RemoveInstructions\n        Search pattern that is used to start the removable of the element\n        \n        Supports wildcard - as it utilizes the -Like operation that is available directly in powershell\n        \n        E.g. \"*<Element Type=\\\"SqlPermissionStatement\\\"*ms_db_configreader*\"\n        \n        End pattern that is used to conclude the removable of the element\n        \n        Supports wildcard - as it utilizes the -Like operation that is available directly in powershell\n        \n        E.g. \"*</Element>*\"\n        \n    .PARAMETER ReplaceInstructions\n        Search pattern that is used to replace the value\n        \n        Works directly on the value entered, no wildcard or regex is supported at all\n        \n        E.g. \"<Property Name=\\\"AutoDrop\\\" Value=\\\"True\\\" />\"\n        \n        Replace value that you want to substitute your search value with\n        \n        E.g. \"\"\n        \n    .EXAMPLE\n        PS C:\\> $removeIns1 = [pscustomobject][ordered]@{Search = '*<Element Type=\"SqlPermissionStatement\"*ms_db_configreader*';End = '*</Element>*'}\n        PS C:\\> $replace1 = [pscustomobject][ordered]@{Search = '<Property Name=\"AutoDrop\" Value=\"True\" />';Replace = ''}\n        PS C:\\> Repair-BacpacModelSimpleAndReplace -Path c:\\temp\\model.xml -OutputPath c:\\temp\\repaired_model.xml -RemoveInstructions @($removeIns1) -ReplaceInstructions @($replace1)\n        \n        This will remove the below section from the model file, based on the RemoveInstructions:\n        \n        <Element Type=\"SqlPermissionStatement\" Name=\"[Grant.Delete.Object].[ms_db_configreader].[dbo].[dbo].[AutotuneBase]\">\n        <Property Name=\"Permission\" Value=\"4\" />\n        <Relationship Name=\"Grantee\">\n        <Entry>\n        <References Name=\"[ms_db_configreader]\" />\n        </Entry>\n        </Relationship>\n        <Relationship Name=\"Grantor\">\n        <Entry>\n        <References ExternalSource=\"BuiltIns\" Name=\"[dbo]\" />\n        </Entry>\n        </Relationship>\n        <Relationship Name=\"SecuredObject\">\n        <Entry>\n        <References Name=\"[dbo].[AutotuneBase]\" />\n        </Entry>\n        </Relationship>\n        </Element>\n        \n        This will remove the below section from the model file, based on the ReplaceInstructions:\n        \n        <Property Name=\"AutoDrop\" Value=\"True\" />\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n        Json files has to be an array directly in the root of the file. All \" (double quotes) has to be escaped with \\\" - otherwise it will not work as intended.\n        \n        This cmdlet is inspired by the work of \"Brad Bateman\" (github: @batetech)\n        \n        His github profile can be found here:\n        https://github.com/batetech\n        \n        Florian Hopfner did a gist implementation, which has been used as the foundation for this implementation\n        \n        The original gist is: https://gist.github.com/FH-Inway/f485c720b43b72bffaca5fb6c094707e\n        \n        His github profile can be found here:\n        https://github.com/FH-Inway\n        \n        https://devblog.pekspro.com/posts/multiple-find-and-replace-with-powershell\n#>\nfunction Repair-BacpacModelSimpleAndReplace {\n    [CmdletBinding()]\n    param (\n        [string] $Path,\n\n        [string] $OutputPath,\n\n        [Object[]] $RemoveInstructions,\n\n        [Object[]] $ReplaceInstructions\n    )\n    Invoke-TimeSignal -Start\n    \n    Write-PSFMessage -Level Verbose -Message \"RemoveInstructions count is: $($RemoveInstructions.Count)\" -Target $RemoveInstructions\n    Write-PSFMessage -Level Verbose -Message \"ReplaceInstructions count is: $($ReplaceInstructions.Count)\" -Target $ReplaceInstructions\n    \n    [int]$flushCounter = 500000\n\n    $buffer = [System.Collections.Generic.List[string]]::new($flushCounter) #much faster than PS array using +=\n    $bufferCounter = 0;\n    \n    try {\n        $stream = [System.IO.StreamReader]::new($Path)\n\n        :LineLoop while ($stream.Peek() -ge 0) {\n            $line = $stream.ReadLine()\n        \n            # Skipping empty lines\n            if (-not [string]::IsNullOrEmpty($line)) {\n\n                # Implement Replace Logic directly here - so we only handle replace once, if the line contains data..\n                foreach ($ReplaceIns in $ReplaceInstructions) {\n                    $line = $line.Replace($ReplaceIns.Search, $ReplaceIns.Replace)\n                }\n\n                foreach ($remove in $RemoveInstructions) {\n                    \n                    if ($line -like $remove.Search) {\n                        # We found the search pattern - next is just removing lines, until we find the end pattern\n\n                        while ($stream.Peek() -ge 0) {\n                            $line = $stream.ReadLine();\n\n                            if ($line -like $remove.End) {\n                                # We found the end tag, so we need to start the line loop again.\n                                continue LineLoop\n                            }\n                        }\n                    }\n                }\n            \n                $buffer.Add($line)\n            }\n            else {\n                $buffer.Add($line)\n            }\n\n            $bufferCounter++;\n            if ($bufferCounter -ge $flushCounter) {\n                $buffer | Add-Content -LiteralPath $OutputPath -Encoding UTF8\n                $buffer = [System.Collections.Generic.List[string]]::new($flushCounter);\n                $bufferCounter = 0;\n            }\n        }\n    }\n    finally {\n        $stream.Close()\n        $stream.Dispose()\n    }\n\n    # Flush anything still remaining in the buffer\n    if ($bufferCounter -gt 0) {\n        $buffer | Add-Content -LiteralPath $OutputPath -Encoding UTF8\n        $buffer = $null;\n        $bufferCounter = 0;\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/select-defaultview.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Short description\n        \n    .DESCRIPTION\n        Long description\n        \n    .PARAMETER InputObject\n        Parameter description\n        \n    .PARAMETER Property\n        Parameter description\n        \n    .PARAMETER ExcludeProperty\n        Parameter description\n        \n    .PARAMETER TypeName\n        Parameter description\n        \n    .EXAMPLE\n        PS C:\\> Select-DefaultView -InputObject $result -Property CommandName, Synopsis\n        \n        This will help you do it right.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Select-DefaultView {\n    <#\n\n    This command enables us to send full on objects to the pipeline without the user seeing it\n    \n    a lot of this is from boe, thanks boe!\n    https://learn-powershell.net/2013/08/03/quick-hits-set-the-default-property-display-in-powershell-on-custom-objects/\n\n    TypeName creates a new type so that we can use ps1xml to modify the output\n    #>\n    \n    [CmdletBinding()]\n    param (\n        [parameter(ValueFromPipeline)]\n        [object]\n        $InputObject,\n        \n        [string[]]\n        $Property,\n        \n        [string[]]\n        $ExcludeProperty,\n        \n        [string]\n        $TypeName\n    )\n    process {\n        \n        if ($null -eq $InputObject) { return }\n        \n        if ($TypeName) {\n            $InputObject.PSObject.TypeNames.Insert(0, \"d365fo.tools.$TypeName\")\n        }\n        \n        if ($ExcludeProperty) {\n            if ($InputObject.GetType().Name.ToString() -eq 'DataRow') {\n                $ExcludeProperty += 'Item', 'RowError', 'RowState', 'Table', 'ItemArray', 'HasErrors'\n            }\n            \n            $props = ($InputObject | Get-Member | Where-Object MemberType -in 'Property', 'NoteProperty', 'AliasProperty' | Where-Object { $_.Name -notin $ExcludeProperty }).Name\n            $defaultset = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet', [string[]]$props)\n        }\n        else {\n            # property needs to be string\n            if (\"$property\" -like \"* as *\") {\n                $newproperty = @()\n                foreach ($p in $property) {\n                    if ($p -like \"* as *\") {\n                        $old, $new = $p -isplit \" as \"\n                        # Do not be tempted to not pipe here\n                        $inputobject | Add-Member -Force -MemberType AliasProperty -Name $new -Value $old -ErrorAction SilentlyContinue\n                        $newproperty += $new\n                    }\n                    else {\n                        $newproperty += $p\n                    }\n                }\n                $property = $newproperty\n            }\n            $defaultset = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet', [string[]]$Property)\n        }\n        \n        $standardmembers = [System.Management.Automation.PSMemberInfo[]]@($defaultset)\n        \n        # Do not be tempted to not pipe here\n        $inputobject | Add-Member -Force -MemberType MemberSet -Name PSStandardMembers -Value $standardmembers -ErrorAction SilentlyContinue\n        \n        $inputobject\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/set-adminuser.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Provision an user to be the administrator of a Dynamics 365 for Finance & Operations environment\n        \n    .DESCRIPTION\n        Provision an user to be the administrator by using the supplied tools from Microsoft (AdminUserProvisioning.exe)\n        \n    .PARAMETER SignInName\n        The sign in name (email address) for the user that you want to be the administrator\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Set-AdminUser -SignInName \"Claire@contoso.com\" -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\"\n        \n        This will provision the user with the e-mail \"Claire@contoso.com\" to be the administrator of the D365 for Finance & Operations instance.\n        It will handle if the tenant is switching also, and update the necessary details.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        Author: Mark Furrer (@devax_mf)\n        \n#>\nfunction Set-AdminUser {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    Param (\n        [string] $SignInName,\n\n        [string] $DatabaseServer,\n\n        [string] $DatabaseName,\n\n        [string] $SqlUser,\n\n        [string] $SqlPwd,\n\n        [switch] $EnableException\n    )\n\n    $WebConfigFile = Join-Path $Script:AOSPath $Script:WebConfig\n\n    $MetaDataNode = Select-Xml -XPath \"/configuration/appSettings/add[@key='Aos.MetadataDirectory']/@value\" -Path $WebConfigFile\n\n    $MetaDataNodeDirectory = $MetaDataNode.Node.Value\n    \n    Write-PSFMessage -Level Verbose -Message \"MetaDataDirectory: $MetaDataNodeDirectory\" -Target $MetaDataNodeDirectory\n\n    $AdminFileLocationPu29AndUp  = \"$MetaDataNodeDirectory\\Bin\\Microsoft.Dynamics.AdminUserProvisioningLib.dll\"\n    $AdminFileLocationBeforePu29 = \"$MetaDataNodeDirectory\\Bin\\AdminUserProvisioning.exe\"\n    if ( Test-Path -Path $AdminFileLocationPu29AndUp -PathType Leaf ) {\n        $AdminFile = $AdminFileLocationPu29AndUp\n        $AdminLibNameSpace = \"Microsoft.Dynamics.AdminUserProvisioningLib\"\n    } else {\n        $AdminFile = $AdminFileLocationBeforePu29\n        $AdminLibNameSpace = \"Microsoft.Dynamics.AdminUserProvisioning\"\n    }\n    Write-PSFMessage -Level Verbose -Message \"Path to AdminFile: $AdminFile\"\n\n    $TempFileName = New-TemporaryFile\n    $TempFileName = $TempFileName.BaseName\n\n    $AdminDll = \"$env:TEMP\\$TempFileName.dll\"\n\n    copy-item -Path $AdminFile -Destination $AdminDll\n\n    $adminAssembly = [System.Reflection.Assembly]::LoadFile($AdminDll)\n\n    $AdminUserUpdater = $adminAssembly.GetType(\"$AdminLibNameSpace.AdminUserUpdater\")\n\n    $PublicBinding = [System.Reflection.BindingFlags]::Public\n    $StaticBinding = [System.Reflection.BindingFlags]::Static\n    $CombinedBinding = $PublicBinding -bor $StaticBinding\n\n    $UpdateAdminUser = $AdminUserUpdater.GetMethod(\"UpdateAdminUser\", $CombinedBinding)\n    \n    Write-PSFMessage -Level Verbose -Message \"Adjusting parameter set to the PU that is in use in this environment.\"\n    if((($UpdateAdminUser.GetParameters()).Name) -contains \"hostUrl\") {\n        Write-PSFMessage -Level Verbose -Message \"PU29 or higher found. Will adjust parameters.\"\n        $params = $SignInName, \"AAD-Global\", $null, $null, $DatabaseServer, $DatabaseName, $SqlUser, $SqlPwd, \"$Script:AOSPath\\\", $Script:Url\n    }\n    elseif((($UpdateAdminUser.GetParameters()).Name) -contains \"providerName\") {\n        Write-PSFMessage -Level Verbose -Message \"PU26/27/28 found. Will adjust parameters.\"\n        $params = $SignInName, \"AAD-Global\", $null, $null, $DatabaseServer, $DatabaseName, $SqlUser, $SqlPwd\n    }\n    else {\n        Write-PSFMessage -Level Verbose -Message \"PU below PU26 found. Will adjust parameters.\"\n        $params = $SignInName, $null, $null, $DatabaseServer, $DatabaseName, $SqlUser, $SqlPwd\n    }\n\n    try {\n\t    $paramsString = $params -join \", \"\n        Write-PSFMessage -Level Verbose -Message \"Updating Admin using the values $paramsString\"\n        $UpdateAdminUser.Invoke($null, $params)\n    }\n    catch {\n        $messageString = \"Something went wrong while <c='em'>provisioning</c> the environment to the new administrator: $SignInName.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target $SignInName\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ -StepsUpward 1\n        return\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/set-azurebacpacvalues.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Change the different Azure SQL Database details\n        \n    .DESCRIPTION\n        When preparing an Azure SQL Database to be the new database for an Tier 2+ environment you need to set different details\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER AxDeployExtUserPwd\n        Password obtained from LCS\n        \n    .PARAMETER AxDbAdminPwd\n        Password obtained from LCS\n        \n    .PARAMETER AxRuntimeUserPwd\n        Password obtained from LCS\n        \n    .PARAMETER AxMrRuntimeUserPwd\n        Password obtained from LCS\n        \n    .PARAMETER AxRetailRuntimeUserPwd\n        Password obtained from LCS\n        \n    .PARAMETER AxRetailDataSyncUserPwd\n        Password obtained from LCS\n        \n    .PARAMETER AxDbReadonlyUserPwd\n        Password obtained from LCS\n        \n    .PARAMETER TenantId\n        The ID of tenant that the Azure SQL Database instance is going to be run under\n        \n    .PARAMETER PlanId\n        The ID of the type of plan that the Azure SQL Database is going to be using\n        \n    .PARAMETER PlanCapability\n        The capabilities that the Azure SQL Database instance will be running with\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Set-AzureBacpacValues -DatabaseServer dbserver1.database.windows.net -DatabaseName Import -SqlUser User123 -SqlPwd \"Password123\" -AxDeployExtUserPwd \"Password123\" -AxDbAdminPwd \"Password123\" -AxRuntimeUserPwd \"Password123\" -AxMrRuntimeUserPwd \"Password123\" -AxRetailRuntimeUserPwd \"Password123\" -AxRetailDataSyncUserPwd \"Password123\" -AxDbReadonlyUserPwd \"Password123\" -TenantId \"TenantIdFromAzure\" -PlanId \"PlanIdFromAzure\" -PlanCapability \"Capabilities\"\n        \n        This will set all the needed details inside the \"Import\" database that is located in the \"dbserver1.database.windows.net\" Azure SQL Database instance.\n        All service accounts and their passwords will be updated accordingly.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Set-AzureBacpacValues {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    [OutputType([System.Boolean])]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseServer,\n\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseName,\n\n        [Parameter(Mandatory = $true)]\n        [string] $SqlUser,\n\n        [Parameter(Mandatory = $true)]\n        [string] $SqlPwd,\n\n        [Parameter(Mandatory = $true)]\n        [string] $AxDeployExtUserPwd,\n\n        [Parameter(Mandatory = $true)]\n        [string] $AxDbAdminPwd,\n\n        [Parameter(Mandatory = $true)]\n        [string] $AxRuntimeUserPwd,\n\n        [Parameter(Mandatory = $true)]\n        [string] $AxMrRuntimeUserPwd,\n\n        [Parameter(Mandatory = $true)]\n        [string] $AxRetailRuntimeUserPwd,\n\n        [Parameter(Mandatory = $true)]\n        [string] $AxRetailDataSyncUserPwd,\n\n        [Parameter(Mandatory = $true)]\n        [string] $AxDbReadonlyUserPwd,\n\n        [Parameter(Mandatory = $true)]\n        [string] $TenantId,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $PlanId,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $PlanCapability,\n\n        [switch] $EnableException\n    )\n        \n    $sqlCommand = Get-SQLCommand -DatabaseServer $DatabaseServer -DatabaseName $DatabaseName -SqlUser $SqlUser -SqlPwd $SqlPwd -TrustedConnection $false\n\n    $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\set-bacpacvaluesazure.sql\") -join [Environment]::NewLine\n\n    $commandText = $commandText.Replace('@axdeployextuser', $AxDeployExtUserPwd)\n    $commandText = $commandText.Replace('@axdbadmin', $AxDbAdminPwd)\n    $commandText = $commandText.Replace('@axruntimeuser', $AxRuntimeUserPwd)\n    $commandText = $commandText.Replace('@axmrruntimeuser', $AxMrRuntimeUserPwd)\n    $commandText = $commandText.Replace('@axretailruntimeuser', $AxRetailRuntimeUserPwd)\n    $commandText = $commandText.Replace('@axretaildatasyncuser', $AxRetailDataSyncUserPwd)\n    $commandText = $commandText.Replace('@axdbreadonlyuser', $AxDbReadonlyUserPwd)\n\n    $sqlCommand.CommandText = $commandText\n\n    $null = $sqlCommand.Parameters.Add(\"@TenantId\", $TenantId)\n    $null = $sqlCommand.Parameters.Add(\"@PlanId\", $PlanId)\n    $null = $sqlCommand.Parameters.Add(\"@PlanCapability \", $PlanCapability)\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n\n        $null = $sqlCommand.ExecuteNonQuery()\n        \n        $true\n    }\n    catch {\n        $messageString = \"Something went wrong while working against the database.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand)\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/set-browserbookmark.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set a new bookmark in the browser\n        \n    .DESCRIPTION\n        Add a new bookmark to the favorite bar in the browser\n        \n        Edge and Chrome behaves the same\n        \n    .PARAMETER PathBrowser\n        Path to the root folder of the profile in the browser\n        \n        Only default is tested / handled\n        \n    .PARAMETER Uri\n        Uri of the system that you want to add as a bookmark\n        \n    .PARAMETER Name\n        Name of the bookmark entry\n        \n    .EXAMPLE\n        PS C:\\> Set-BrowserBookmark -PathBrowser 'C:\\Users\\Admin....\\AppData\\Local\\Microsoft\\Edge\\User Data\\Default' -Uri 'https://devdevaos.axcloud.dynamics.com/?cmp=DAT&mi=DefaultDashboard' -Name \"D365FO\"\n        \n        This will work against the Edge browser.\n        The bookmark will be for the 'https://devdevaos.axcloud.dynamics.com/?cmp=DAT&mi=DefaultDashboard' system.\n        The name will be \"D365FO\".\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\nfunction Set-BrowserBookmark {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    param (\n        [string] $PathBrowser,\n\n        [string] $Uri,\n\n        [string] $Name\n    )\n\n    $pathBase = \"$PathBrowser\"\n\n    if ((Test-PathExists -Path $pathBase -Type Container)) {\n        $prefRaw = Get-Content -Path \"$pathBase\\Preferences\" -Raw\n        $prefObj = $prefRaw | ConvertFrom-Json\n\n        if ($null -eq $prefObj.bookmark_bar) {\n            # Sometimes the needed settings is missing\n            $prefRaw.Replace(',\"browser\":', ',\"bookmark_bar\":{\"show_on_all_tabs\": true,\"show_only_on_ntp\":false},\"browser\":') | Out-File -FilePath \"$pathBase\\Preferences\" -Encoding utf8 -Force\n        }\n        else {\n            $prefObj.bookmark_bar.show_on_all_tabs = $true\n            $($prefObj | ConvertTo-Json -Depth 10).Replace(\"`r`n\", \"\") | Out-File -FilePath \"$pathBase\\Preferences\" -Encoding utf8 -Force > $null\n        }\n\n        if (-not (Test-PathExists -Path \"$pathBase\\Bookmarks\" -Type Leaf)) {\n            # We might be handling bookmarks / favorites for the first time\n            Copy-Item -Path \"$script:ModuleRoot\\internal\\misc\\Bookmarks\" -Destination \"$pathBase\\Bookmarks\" -Force > $null\n        }\n\n        $favRaw = Get-Content -Path \"$pathBase\\Bookmarks\" -Raw\n        $favObj = $favRaw | ConvertFrom-Json\n    \n        # If any bookmarks already exists - we need to up the counter / id\n        $id = [int]$($favObj.roots.bookmark_bar.children.id | Sort-Object -Descending | Select-Object -First 1)\n        $id++\n\n        $bookMark = [PsCustomObject][Ordered]@{\n            guid = [System.Guid]::NewGuid().Guid\n            id   = $id\n            name = $name\n            type = \"url\"\n            url  = $URL\n        }\n\n        # The children property is an array - which is a fixed size\n        $children = [System.Collections.Generic.List[System.Object]]::new($favObj.roots.bookmark_bar.children)\n        \n        $children.Add($bookMark)\n        $favObj.roots.bookmark_bar.children = $children.ToArray()\n        $($favObj | ConvertTo-Json -Depth 10) | Out-File -FilePath \"$pathBase\\Bookmarks\" -Encoding utf8 -Force > $null\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/set-sqlbacpacvalues.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Set the SQL Server specific values\n        \n    .DESCRIPTION\n        Set the SQL Server specific values when restoring a bacpac file\n        \n    .PARAMETER DatabaseServer\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n    .PARAMETER DatabaseName\n        The name of the database\n        \n    .PARAMETER SqlUser\n        The login name for the SQL Server instance\n        \n    .PARAMETER SqlPwd\n        The password for the SQL Server user\n        \n    .PARAMETER TrustedConnection\n        Should the connection use a Trusted Connection or not\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Set-SqlBacpacValues -DatabaseServer localhost -DatabaseName \"AxDB\" -SqlUser \"User123\" -SqlPwd \"Password123\"\n        \n        This will connect to the \"AXDB\" database that is available in the SQL Server instance running on the localhost.\n        It will use the \"User123\" SQL Server credentials to connect to the SQL Server instance.\n        This will set all the necessary SQL Server database options and create the needed objects in side the \"AxDB\" database.\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Set-SqlBacpacValues {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    [OutputType('System.Boolean')]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseServer,\n\n        [Parameter(Mandatory = $true)]\n        [string] $DatabaseName,\n\n        [Parameter(Mandatory = $false)]\n        [string] $SqlUser,\n\n        [Parameter(Mandatory = $false)]\n        [string] $SqlPwd,\n        \n        [Parameter(Mandatory = $false)]\n        [bool] $TrustedConnection,\n\n        [switch] $EnableException\n    )\n    \n    $Params = @{DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName;\n        SqlUser = $SqlUser; SqlPwd = $SqlPwd; TrustedConnection = $TrustedConnection;\n    }\n\n    # We have learned that pooling keeps the connection open and that is not what we want\n    $sqlCommand = Get-SQLCommand @Params -NoPooling\n\n    $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\set-bacpacvaluessql.sql\") -join [Environment]::NewLine\n    $commandText = $commandText.Replace('@DATABASENAME', $DatabaseName)\n\n    $sqlCommand.CommandText = $commandText\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $sqlCommand.Connection.Open()\n\n        $sqlCommand.ExecuteNonQuery()\n\n        $true\n    }\n    catch {\n        $messageString = \"Something went wrong while working against the database.\"\n        Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand)\n        Stop-PSFFunction -Message \"Stopping because of errors.\" -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_\n        return\n    }\n    finally {\n        if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) {\n            $sqlCommand.Connection.Close()\n        }\n\n        $sqlCommand.Dispose()\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/start-lcsdatabaseexportv2.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Start a database export from an environment\n        \n    .DESCRIPTION\n        Start a database export from an environment from a LCS project\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER SourceEnvironmentId\n        The unique id of the environment that you want to use as the source for the database export\n        \n        The Id can be located inside the LCS portal\n        \n    .PARAMETER BackupName\n        Name of the backup file when it is being exported from the environment\n        \n        The file shouldn't contain any extension at all, just the desired file name\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Start-LcsDatabaseExportV2 -ProjectId 123456789 -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -BackupName \"BackupViaApi\" -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will start the database export from the Source environment.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\n        The backup name is identified by the BackupName \"BackupViaApi\", which instructs the API to save the backup with that filename.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .LINK\n        Get-LcsDatabaseOperationStatus\n        \n    .NOTES\n        Tags: Environment, Config, Configuration, LCS, Database backup, Api, Backup, Bacpac\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Start-LcsDatabaseExportV2 {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Cmdletbinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [int] $ProjectId,\n    \n        [Parameter(Mandatory = $true)]\n        [Alias('Token')]\n        [string] $BearerToken,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $SourceEnvironmentId,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $BackupName,\n\n        [Parameter(Mandatory = $true)]\n        [string] $LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n    \n    begin {\n        Invoke-TimeSignal -Start\n        \n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"POST\"\n        $parms.Uri = \"$LcsApiUri/databasemovement/v1/export/project/$($ProjectId)/environment/$($SourceEnvironmentId)/backupName/$($BackupName)\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n    }\n\n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in starting a new database export in LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception -Target $_\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/start-lcsdatabaserefreshv2.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Start a database refresh between 2 environments\n        \n    .DESCRIPTION\n        Start a database refresh between 2 environments from a LCS project\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER SourceEnvironmentId\n        The unique id of the environment that you want to use as the source for the database refresh\n        \n        The Id can be located inside the LCS portal\n        \n    .PARAMETER TargetEnvironmentId\n        The unique id of the environment that you want to use as the target for the database refresh\n        \n        The Id can be located inside the LCS portal\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Start-LcsDatabaseRefreshV2 -ProjectId 123456789 -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will start the database refresh between the Source and Target environments.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\n        The target environment is identified by the TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .LINK\n        Get-LcsDatabaseOperationStatus\n        \n    .NOTES\n        Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token, Deployment, Deployable Package\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Start-LcsDatabaseRefreshV2 {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Cmdletbinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [int] $ProjectId,\n    \n        [Parameter(Mandatory = $true)]\n        [Alias('Token')]\n        [string] $BearerToken,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $SourceEnvironmentId,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $TargetEnvironmentId,\n\n        [Parameter(Mandatory = $true)]\n        [string] $LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n        \n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"POST\"\n        $parms.Uri = \"$LcsApiUri/databasemovement/v1/refresh/project/$($ProjectId)/source/$($SourceEnvironmentId)/target/$($TargetEnvironmentId)\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n    }\n\n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in starting a new database refresh in LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception -Target $_\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/start-lcsdeploymentv2.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Start LCS deployment\n        \n    .DESCRIPTION\n        Start the deployment of a deployable package from the LCS API\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER AssetId\n        The unique id of the asset / file that you are trying to deploy from LCS\n        \n    .PARAMETER EnvironmentId\n        The unique id of the environment that you want to work against\n        \n        The Id can be located inside the LCS portal\n        \n    .PARAMETER UpdateName\n        Name of the update when you are working against Self-Service environments\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Start-LcsDeploymentV2 -BearerToken \"Bearer JldjfafLJdfjlfsalfd...\" -ProjectId 123456789 -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will start the deployment of the file located in the Asset Library.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\n        The environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"Bearer JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n        \n    .NOTES\n        Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token, Deployment, Deployable Package\n        \n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Start-LcsDeploymentV2 {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Cmdletbinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [int] $ProjectId,\n    \n        [Parameter(Mandatory = $true)]\n        [Alias('Token')]\n        [string] $BearerToken,\n\n        [Parameter(Mandatory = $true)]\n        [string] $AssetId,\n\n        [Parameter(Mandatory = $true)]\n        [string] $EnvironmentId,\n        \n        [Parameter(Mandatory = $false)]\n        [string] $UpdateName,\n\n        [Parameter(Mandatory = $true)]\n        [string] $LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n        \n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"POST\"\n        $parms.Uri = \"$LcsApiUri/environment/v2/applyupdate/project/$($ProjectId)/environment/$($EnvironmentId)/asset/$($AssetId)?updateName=$($UpdateName)\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n    }\n\n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in starting a new deployment in LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception -Target $_\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/start-lcsenvironmentstartstopv2.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Start or stop a given environment using LCS\n        \n    .DESCRIPTION\n        Start or stop a specified IAAS environment that is Customer Managed through the LCS API.\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER EnvironmentId\n        The unique id of the environment that you want to take action upon\n        \n        The Id can be located inside the LCS portal\n        \n    .PARAMETER IsStop\n        When set to True, the environment will be stopped. When set to False, the environment will be started.\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Start-LcsEnvironmentStartStopV2 -ProjectId 123456789 -EnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -IsStop $False -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will trigger the environment start operation upon the given environment through the LCS API.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The environment is identified by the EnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n    .EXAMPLE\n        PS C:\\> Start-LcsEnvironmentStartStopV2 -ProjectId 123456789 -EnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -IsStop $True -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will trigger the environment stop operation upon the given environment through the LCS API.\n        The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n        The environment is identified by the EnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\n        The request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\n        The http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n    .NOTES\n        Tags: Environment, Stop, Start, LCS, Api, AAD, Token\n        \n        Author: Mötz Jensen (@Splaxi), Billy Richardson (@richardsondev)\n#>\n\nfunction Start-LcsEnvironmentStartStopV2 {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Cmdletbinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [int] $ProjectId,\n    \n        [Parameter(Mandatory = $true)]\n        [Alias('Token')]\n        [string] $BearerToken,\n        \n        [Parameter(Mandatory = $true)]\n        [string] $EnvironmentId,\n\n        [Parameter(Mandatory = $true)]\n        [boolean] $IsStop,\n\n        [Parameter(Mandatory = $true)]\n        [string] $LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n        \n        $internalAction = \"start\";\n    \n        if ($IsStop -eq $True) {\n            $internalAction = \"stop\";\n        }\n    \n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"POST\"\n        $parms.Uri = \"$LcsApiUri/environment/v1/$($internalAction)/project/$($ProjectId)/environment/$($EnvironmentId)\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n    }\n\n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in starting a new deployment in LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception -Target $_\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/start-lcsuploadv2.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Start the upload process to LCS\n        \n    .DESCRIPTION\n        Start the flow of actions to upload a file to LCS\n        \n    .PARAMETER BearerToken\n        The token you want to use when working against the LCS api\n        \n    .PARAMETER ProjectId\n        The project id for the Dynamics 365 for Finance & Operations project inside LCS\n        \n    .PARAMETER FileType\n        Type of file you want to upload\n        \n        Valid options:\n        \"Model\"\n        \"Process Data Package\"\n        \"Software Deployable Package\"\n        \"GER Configuration\"\n        \"Data Package\"\n        \"PowerBI Report Model\"\n        \"E-Commerce Package\"\n        \"NuGet Package\"\n        \"Retail Self-Service Package\"\n        \"Commerce Cloud Scale Unit Extension\"\n        \n    .PARAMETER Name\n        Name to be assigned / shown on LCS\n        \n    .PARAMETER Filename\n        Filename to be assigned / shown on LCS\n        \n        Often will it require an extension for it to be accepted\n        \n    .PARAMETER Description\n        Description to be assigned / shown on LCS\n        \n    .PARAMETER LcsApiUri\n        URI / URL to the LCS API you want to use\n        \n        The value depends on where your LCS project is located. There are multiple valid URI's / URL's\n        \n        Valid options:\n        \"https://lcsapi.lcs.dynamics.com\"\n        \"https://lcsapi.eu.lcs.dynamics.com\"\n        \"https://lcsapi.fr.lcs.dynamics.com\"\n        \"https://lcsapi.sa.lcs.dynamics.com\"\n        \"https://lcsapi.uae.lcs.dynamics.com\"\n        \"https://lcsapi.ch.lcs.dynamics.com\"\n        \"https://lcsapi.no.lcs.dynamics.com\"\n        \"https://lcsapi.lcs.dynamics.cn\"\n        \"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n        \n    .PARAMETER RetryTimeout\n        The retry timeout, before the cmdlet should quit retrying based on the 429 status code\n        \n        Needs to be provided in the timspan notation:\n        \"hh:mm:ss\"\n        \n        hh is the number of hours, numerical notation only\n        mm is the number of minutes\n        ss is the numbers of seconds\n        \n        Each section of the timeout has to valid, e.g.\n        hh can maximum be 23\n        mm can maximum be 59\n        ss can maximum be 59\n        \n        Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n        \n    .PARAMETER EnableException\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n    .EXAMPLE\n        PS C:\\> Start-LcsUploadV2 -Token \"Bearer JldjfafLJdfjlfsalfd...\" -ProjectId 123456789 -FileType \"SoftwareDeployablePackage\" -Name \"ReadyForTesting\" -Filename \"ReadyForTesting.zip\" -Description \"Latest release that fixes it all\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n        \n        This will contact the NON-EUROPE LCS API and instruct it that we want to upload a new file to the Asset Library.\n        The token \"Bearer JldjfafLJdfjlfsalfd...\" is used to the authorize against the LCS API.\n        The ProjectId is 123456789 and FileType is \"SoftwareDeployablePackage\".\n        The file will be named \"ReadyForTesting\" and the Description will be \"Latest release that fixes it all\".\n        \n    .NOTES\n        Tags: Url, LCS, Upload, Api, Token\n        \n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Start-LcsUploadV2 {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Cmdletbinding()]\n    param(\n        [Parameter(Mandatory = $true)]\n        [Alias('Token')]\n        [string] $BearerToken,\n\n        [Parameter(Mandatory = $true)]\n        [int] $ProjectId,\n\n        [Parameter(Mandatory = $true)]\n        [LcsAssetFileType] $FileType,\n\n        [string] $Name,\n\n        [string] $Filename,\n\n        [string] $Description,\n\n        [string] $LcsApiUri,\n\n        [Timespan] $RetryTimeout = \"00:00:00\",\n\n        [switch] $EnableException\n    )\n\n    begin {\n        Invoke-TimeSignal -Start\n        \n        $fileTypeValue = [int]$FileType\n        $jsonPayload = @{\n            Name            = $Name\n            FileName        = $Filename\n            FileDescription = $Description\n            SizeByte        = 0\n            FileType        = $fileTypeValue\n        } | ConvertTo-Json\n\n        $headers = @{\n            \"Authorization\" = \"$BearerToken\"\n        }\n\n        $parms = @{}\n        $parms.Method = \"POST\"\n        $parms.Uri = \"$LcsApiUri/box/fileasset/CreateFileAsset/$ProjectId\"\n        $parms.Headers = $headers\n        $parms.RetryTimeout = $RetryTimeout\n        $parms.Payload = $jsonPayload\n        $parms.ContentType = \"application/json\"\n    }\n    \n    process {\n        try {\n            Write-PSFMessage -Level Verbose -Message \"Invoke LCS request.\"\n            Invoke-RequestHandler @parms\n        }\n        catch [System.Net.WebException] {\n            Write-PSFMessage -Level Host -Message \"Error status code <c='em'>$($_.exception.response.statuscode)</c> in starting a new deployment in LCS. <c='em'>$($_.exception.response.StatusDescription)</c>.\" -Exception $PSItem.Exception -Target $_\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n        catch {\n            Write-PSFMessage -Level Host -Message \"Something went wrong while working against the LCS API.\" -Exception $PSItem.Exception\n            Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n            return\n        }\n\n        Invoke-TimeSignal -End\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/test-aaduseridind365fo.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Test to see if a given user ID exists\n        \n    .DESCRIPTION\n        Test to see if a given user ID exists in the Dynamics 365 for Finance & Operations instance\n        \n    .PARAMETER SqlCommand\n        The SQL Command object that should be used when testing the user ID\n        \n    .PARAMETER Id\n        Id of the user that you want to test exists or not\n        \n    .EXAMPLE\n        PS C:\\> $SqlCommand = Get-SqlCommand -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\"\n        PS C:\\> Test-AadUserIdInD365FO -SqlCommand $SqlCommand -Id \"TestUser\"\n        \n        This will get a SqlCommand object that will connect to the localhost server and the AXDB database, with the sql credential \"User123\".\n        It will query the the database for any user with the Id \"TestUser\".\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Test-AadUserIdInD365FO {\n\n    param (\n        [System.Data.SqlClient.SqlCommand] $SqlCommand,\n        [string] $Id\n    )\n\n    $commandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\test-aaduseridind365fo.sql\") -join [Environment]::NewLine\n\n    $sqlCommand.CommandText = $commandText\n\n    $null = $sqlCommand.Parameters.Add(\"@Id\", $Id)\n\n    Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n    $NumFound = $sqlCommand.ExecuteScalar()\n\n    Write-PSFMessage -Level Verbose -Message  \"Number of user rows found in database $NumFound\" -Target $NumFound\n    $SqlCommand.Parameters.Clear()\n\n    $NumFound -ne 0\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/test-aaduserind365fo.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Test to see if a given user already exists\n        \n    .DESCRIPTION\n        Test to see if a given user already exists in the Dynamics 365 for Finance & Operations instance\n        \n    .PARAMETER SqlCommand\n        The SQL Command object that should be used when testing the user\n        \n    .PARAMETER SignInName\n        The sign in name (email address) for the user that you want test\n        \n    .EXAMPLE\n        PS C:\\> $SqlCommand = Get-SqlCommand -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\"\n        PS C:\\> Test-AadUserInD365FO -SqlCommand $SqlCommand -SignInName \"Claire@contoso.com\"\n        \n        This will get a SqlCommand object that will connect to the localhost server and the AXDB database, with the sql credential \"User123\".\n        It will query the the database for the user with the e-mail address \"Claire@contoso.com\".\n        \n    .NOTES\n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Test-AadUserInD365FO {\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [System.Data.SqlClient.SqlCommand] $SqlCommand,\n\n        [Parameter(Mandatory = $true)]\n        [string] $SignInName\n    )\n\n    $sqlCommand.CommandText = (Get-Content \"$script:ModuleRoot\\internal\\sql\\test-aaduserind365fo.sql\") -join [Environment]::NewLine\n\n    $null = $sqlCommand.Parameters.Add(\"@Email\", $SignInName)\n\n    try {\n        Write-PSFMessage -Level InternalComment -Message \"Executing a script against the database.\" -Target (Get-SqlString $SqlCommand)\n\n        $NumFound = $sqlCommand.ExecuteScalar()\n\n        Write-PSFMessage -Level Verbose -Message \"Number of user rows found in database $NumFound\" -Target $NumFound\n    }\n    catch {\n        Write-PSFMessage -Level Host -Message \"Something went wrong while working against the database\" -Exception $PSItem.Exception\n        Stop-PSFFunction -Message \"Stopping because of errors\" -StepsUpward 1\n        return\n    }\n    finally {\n        $SqlCommand.Parameters.Clear()\n    }\n\n    $NumFound -ne 0\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/test-assembliesloaded.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Test if any D365 assemblies are loaded\n        \n    .DESCRIPTION\n        Test if any D365 assemblies are loaded into memory and will be a blocking issue\n        \n    .EXAMPLE\n        PS C:\\> Test-AssembliesLoaded\n        \n        This will test in any D365 specific assemblies are loaded into memory.\n        If is, a Stop-PSFFunction test will state that we should stop execution.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\n\nfunction Test-AssembliesLoaded {\n    [CmdletBinding()]\n    [OutputType()]\n    param (\n    )\n\n    Invoke-TimeSignal -Start\n\n    $assembliesLoaded = [System.AppDomain]::CurrentDomain.GetAssemblies() | Where-Object Location -ne $null\n\n    $assembliesBlocking = $assembliesLoaded.location -match \"AOSService|Dynamics|PackagesLocalDirectory\"\n\n    if ($assembliesBlocking.Count -gt 0) {\n        Stop-PSFFunction -Message \"Stopping because some assembly (DLL) files seems to be loaded into memory.\" -StepsUpward 1\n        return\n    }\n\n    Invoke-TimeSignal -End\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/test-configstoreagelocation.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Test accessible to the configuration storage\n        \n    .DESCRIPTION\n        Test if the desired configuration storage is accessible with the current user context\n        \n    .PARAMETER ConfigStorageLocation\n        Parameter used to instruct where to store the configuration objects\n        \n        The default value is \"User\" and this will store all configuration for the active user\n        \n        Valid options are:\n        \"User\"\n        \"System\"\n        \n        \"System\" will store the configuration so all users can access the configuration objects\n        \n    .EXAMPLE\n        PS C:\\> Test-ConfigStorageLocation -ConfigStorageLocation \"System\"\n        \n        This will test if the current executing user has enough privileges to save to the system wide configuration storage.\n        The system wide configuration storage requires administrator rights.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nfunction Test-ConfigStorageLocation {\n    [CmdletBinding()]\n    [OutputType('System.String')]\n    param (\n        [ValidateSet('User', 'System')]\n        [string] $ConfigStorageLocation = \"User\"\n    )\n    \n    $configScope = \"UserDefault\"\n\n    if ($ConfigStorageLocation -eq \"System\") {\n        if ($Script:IsAdminRuntime) {\n            $configScope = \"SystemDefault\"\n        }\n        else {\n            Write-PSFMessage -Level Host -Message \"Unable to locate save the <c='em'>configuration objects</c> in the <c='em'>system wide configuration store</c> on the machine. Please start an elevated session and run the cmdlet again.\"\n            Stop-PSFFunction -Message \"Elevated permissions needed. Please start an elevated session and run the cmdlet again.\" -StepsUpward 1\n            return\n        }\n    }\n\n    $configScope\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/test-pathexists.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Test multiple paths\n        \n    .DESCRIPTION\n        Easy way to test multiple paths for public functions and have the same error handling\n        \n    .PARAMETER Path\n        Array of paths you want to test\n        \n        They have to be the same type, either file/leaf or folder/container\n        \n    .PARAMETER Type\n        Type of path you want to test\n        \n        Either 'Leaf' or 'Container'\n        \n    .PARAMETER Create\n        Instruct the cmdlet to create the directory if it doesn't exist\n        \n    .PARAMETER ShouldNotExist\n        Instruct the cmdlet to return true if the file doesn't exists\n        \n    .EXAMPLE\n        PS C:\\> Test-PathExists \"c:\\temp\",\"c:\\temp\\dir\" -Type Container\n        \n        This will test if the mentioned paths (folders) exists and the current context has enough permission.\n        \n    .NOTES\n        Author: Mötz Jensen (@splaxi)\n        \n#>\nfunction Test-PathExists {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    [OutputType([System.Boolean])]\n    param (\n        [Parameter(Mandatory = $True)]\n        [AllowEmptyString()]\n        [string[]] $Path,\n\n        [ValidateSet('Leaf', 'Container')]\n        [Parameter(Mandatory = $True)]\n        [string] $Type,\n\n        [switch] $Create,\n\n        [switch] $ShouldNotExist\n    )\n    \n    $res = $false\n\n    $arrList = New-Object -TypeName \"System.Collections.ArrayList\"\n         \n    foreach ($item in $Path) {\n\n        if ([string]::IsNullOrEmpty($item)) {\n            Stop-PSFFunction -Message \"Stopping because path was either null or empty string.\" -StepsUpward 1\n            return\n        }\n\n        Write-PSFMessage -Level Debug -Message \"Testing the path: $item\" -Target $item\n        $temp = Test-Path -Path $item -Type $Type\n\n        if ((-not $temp) -and ($Create) -and ($Type -eq \"Container\")) {\n            Write-PSFMessage -Level Debug -Message \"Creating the path: $item\" -Target $item\n            $null = New-Item -Path $item -ItemType Directory -Force -ErrorAction Stop\n            $temp = $true\n        }\n        elseif ($ShouldNotExist) {\n            Write-PSFMessage -Level Debug -Message \"The should NOT exists: $item\" -Target $item\n        }\n        elseif ((-not $temp) -and ($WarningPreference -ne [System.Management.Automation.ActionPreference]::SilentlyContinue)) {\n            Write-PSFMessage -Level Host -Message \"The <c='em'>$item</c> path wasn't found. Please ensure the path <c='em'>exists</c> and you have enough <c='em'>permission</c> to access the path.\"\n        }\n        \n        $null = $arrList.Add($temp)\n    }\n\n    if ($arrList.Contains($false) -and (-not $ShouldNotExist)) {\n        # The $ErrorActionPreference variable determines the behavior we are after, but the \"Stop-PSFFunction -WarningAction\" is where we need to put in the value.\n        Stop-PSFFunction -Message \"Stopping because of missing paths.\" -StepsUpward 1 -WarningAction $ErrorActionPreference\n        \n    }\n    elseif ($arrList.Contains($true) -and $ShouldNotExist) {\n        # The $ErrorActionPreference variable determines the behavior we are after, but the \"Stop-PSFFunction -WarningAction\" is where we need to put in the value.\n        Stop-PSFFunction -Message \"Stopping because file exists.\" -StepsUpward 1 -WarningAction $ErrorActionPreference\n    }\n    else {\n        $res = $true\n    }\n\n    $res\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/test-registryvalue.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Test if a given registry key exists or not\n        \n    .DESCRIPTION\n        Test if a given registry key exists in the path specified\n        \n    .PARAMETER Path\n        Path to the registry hive and sub directories you want to work against\n        \n    .PARAMETER Name\n        Name of the registry key that you want to test for\n        \n    .EXAMPLE\n        PS C:\\> Test-RegistryValue -Path \"HKLM:\\SOFTWARE\\Microsoft\\Dynamics\\Deployment\\\" -Name \"InstallationInfoDirectory\"\n        \n        This will query the LocalMachine hive and the sub directories \"HKLM:\\SOFTWARE\\Microsoft\\Dynamics\\Deployment\\\" for a registry key with the name of \"InstallationInfoDirectory\".\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n        \n#>\nFunction Test-RegistryValue {\n    [OutputType('System.Boolean')]\n    param(\n        [Parameter(Mandatory = $true)]\n        [string]$Path,\n        \n        [Parameter(Mandatory = $true)]\n        [string]$Name\n    )\n\n    if (Test-Path -Path $Path -PathType Any) {\n        $null -ne (Get-ItemProperty $Path).$Name\n    }\n    else {\n        $false\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/test-trustedconnection.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Test PSBoundParameters whether or not to support TrustedConnection\n        \n    .DESCRIPTION\n        Test callers PSBoundParameters (HashTable) for details that determines whether or not a SQL Server connection should support TrustedConnection or not\n        \n    .PARAMETER Inputs\n        HashTable ($PSBoundParameters) with the parameters from the callers invocation\n        \n    .EXAMPLE\n        PS C:\\> $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters\n        \n        This will send the entire HashTable from the callers invocation, containing all explicit defined parameters to be analyzed whether or not the SQL Server connection should support TrustedConnection or not.\n        \n    .NOTES\n        Author: Mötz Jensen (@splaxi)\n        \n#>\nfunction Test-TrustedConnection {\n    [CmdletBinding()]\n    [OutputType([System.Boolean])]\n    param (\n        [HashTable] $Inputs\n    )\n\n    if (($Inputs.ContainsKey(\"ImportModeTier2\")) -or ($Inputs.ContainsKey(\"ExportModeTier2\"))){\n        Write-PSFMessage -Level Verbose -Message \"Not capable of using Trusted Connection based on Tier validation.\"\n        $false\n    }\n    elseif (($Inputs.ContainsKey(\"SqlUser\")) -or ($Inputs.ContainsKey(\"SqlPwd\"))) {\n        Write-PSFMessage -Level Verbose -Message \"Not capable of using Trusted Connection based on supplied SQL login details.\"\n        $false\n    }\n    elseif ($Inputs.ContainsKey(\"TrustedConnection\")) {\n        Write-PSFMessage -Level Verbose -Message \"The script was calling with TrustedConnection directly. This overrides all other logic in respect that the caller should know what it is doing. Value was: $($Inputs.TrustedConnection)\" -Tag $Inputs.TrustedConnection\n        $Inputs.TrustedConnection\n    }\n    else {\n        Write-PSFMessage -Level Verbose -Message \"Capabilities based on the centralized logic in the psm1 file.\" -Target $Script:CanUseTrustedConnection\n        $Script:CanUseTrustedConnection\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/update-azurestoragevariables.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Update the Azure Storage config variables\n        \n    .DESCRIPTION\n        Update the active Azure Storage config variables that the module will use as default values\n        \n    .EXAMPLE\n        PS C:\\> Update-AzureStorageVariables\n        \n        This will update the Azure Storage variables.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Update-AzureStorageVariables {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    [OutputType()]\n    param ( )\n    \n    $hashParameters = Get-D365ActiveAzureStorageConfig\n\n    foreach ($item in $hashParameters.Keys) {\n            \n        $name = \"AzureStorage\" + (Get-Culture).TextInfo.ToTitleCase($item)\n        \n        Write-PSFMessage -Level Verbose -Message \"$name - $($hashParameters[$item])\" -Target $hashParameters[$item]\n        Set-Variable -Name $name -Value $hashParameters[$item] -Scope Script\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/update-broadcastvariables.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Update the broadcast message config variables\n        \n    .DESCRIPTION\n        Update the active broadcast message config variables that the module will use as default values\n        \n    .EXAMPLE\n        PS C:\\> Update-BroadcastVariables\n        \n        This will update the broadcast variables.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Update-BroadcastVariables {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    [OutputType()]\n    param ( )\n\n    $configName = (Get-PSFConfig -FullName \"d365fo.tools.active.broadcast.message.config.name\").Value.ToString().ToLower()\n    if (-not ($configName -eq \"\")) {\n        $hashParameters = Get-D365ActiveBroadcastMessageConfig -OutputAsHashtable\n        foreach ($item in $hashParameters.Keys) {\n            if ($item -eq \"name\") { continue }\n            \n            $name = \"Broadcast\" + (Get-Culture).TextInfo.ToTitleCase($item)\n        \n            $valueMessage = $hashParameters[$item]\n\n            if ($item -like \"*client*\" -and $valueMessage.Length -gt 20)\n            {\n                $valueMessage = $valueMessage.Substring(0,18) + \"[...REDACTED...]\"\n            }\n\n            Write-PSFMessage -Level Verbose -Message \"$name - $valueMessage\" -Target $valueMessage\n            Set-Variable -Name $name -Value $hashParameters[$item] -Scope Script\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/update-lcsapivariables.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Update the LCS API config variables\n        \n    .DESCRIPTION\n        Update the active LCS API config variables that the module will use as default values\n        \n    .EXAMPLE\n        PS C:\\> Update-LcsApiVariables\n        \n        This will update the LCS API variables.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Update-LcsApiVariables {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    [OutputType()]\n    param ( )\n    \n    $hashParameters = Get-D365LcsApiConfig -OutputAsHashtable\n\n    foreach ($item in $hashParameters.Keys) {\n            \n        $name = \"LcsApi\" + (Get-Culture).TextInfo.ToTitleCase($item)\n        \n        $valueMessage = $hashParameters[$item]\n\n        if ($item -like \"*client*\" -and $valueMessage.Length -gt 20)\n        {\n            $valueMessage = $valueMessage.Substring(0,18) + \"[...REDACTED...]\"\n        }\n\n        Write-PSFMessage -Level Verbose -Message \"$name - $valueMessage\" -Target $valueMessage\n        Set-Variable -Name $name -Value $hashParameters[$item] -Scope Script\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/update-modulevariables.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Update module variables\n        \n    .DESCRIPTION\n        Loads configuration variables again, to make sure things are updated based on changed configuration\n        \n    .EXAMPLE\n        PS C:\\> Update-ModuleVariables\n        \n        This will update internal variables that the module is dependent on.\n        \n    .NOTES\n        Author: Mötz Jensen (@Splaxi)\n#>\n\nfunction Update-ModuleVariables {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [CmdletBinding()]\n    [OutputType()]\n    param ( )\n\n    Update-PsfConfigVariables\n\n    $Script:AADOAuthEndpoint = Get-PSFConfigValue -FullName \"d365fo.tools.azure.common.oauth.token\"\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/update-psfconfigvariables.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Update the module variables based on the PSF Configuration store\n        \n    .DESCRIPTION\n        Will read the current PSF Configuration store and create local module variables\n        \n    .EXAMPLE\n        PS C:\\> Update-PsfConfigVariables\n        \n        This will read all relevant PSF Configuration values and create matching module variables.\n        \n    .NOTES\n        Author: Mötz Jensen (@splaxi)\n#>\n\nfunction Update-PsfConfigVariables {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseSingularNouns\", \"\")]\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n\n    [CmdletBinding()]\n    [OutputType()]\n    param ()\n\n    foreach ($config in Get-PSFConfig -FullName \"d365fo.tools.path.*\") {\n        $item = $config.FullName.Replace(\"d365fo.tools.path.\", \"\")\n        $name = (Get-Culture).TextInfo.ToTitleCase($item) + \"Path\"\n        \n        Set-Variable -Name $name -Value $config.Value -Scope Script\n    }\n}"
  },
  {
    "path": "d365fo.tools/internal/functions/update-topologyfile.ps1",
    "content": "﻿\n<#\n    .SYNOPSIS\n        Update the topology file\n        \n    .DESCRIPTION\n        Update the topology file based on the already installed list of services on the machine\n        \n    .PARAMETER Path\n        Path to the folder where the Microsoft.Dynamics.AX.AXInstallationInfo.dll assembly is located\n        \n        Should only contain a path to a folder, not a file\n        \n    .PARAMETER TopologyFile\n        Path to the topology file to update\n        \n        If not specified, the default topology file will be used\n        \n    .PARAMETER IncludeFallbackRetailServiceModels\n        Include fallback retail service models in the topology file\n        \n        This parameter is to support backward compatibility in this scenario:\n        Installing the first update on a local VHD where the information about the installed service\n        models may not be available and where the retail components are installed.\n        More information about this can be found at https://github.com/d365collaborative/d365fo.tools/issues/878\n        \n    .PARAMETER ForceFallbackServiceModels\n        Force the use of the fallback list of known service model names\n        \n        This parameter supports update scenarios primarily on local VHDs where the information about\n        the installed service models may be incomplete. In such a case, the user receives a warning\n        and a suggestion to use this parameter.\n        \n    .EXAMPLE\n        PS C:\\> Update-TopologyFile -Path \"c:\\temp\\UpdatePackageFolder\" -TopologyFile \"c:\\temp\\d365fo.tools\\DefaultTopologyData.xml\"\n        \n        This will update the \"c:\\temp\\d365fo.tools\\DefaultTopologyData.xml\" file with all the installed services on the machine.\n        \n    .NOTES\n        # Credit http://dev.goshoom.net/en/2016/11/installing-deployable-packages-with-powershell/\n        \n        Author: Tommy Skaue (@Skaue)\n        Author: Mötz Jensen (@Splaxi)\n        Author: Florian Hopfner (@FH-Inway)\n        \n#>\nfunction Update-TopologyFile {\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"PSUseShouldProcessForStateChangingFunctions\", \"\")]\n    [CmdletBinding()]\n    [OutputType([System.Boolean])]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string]$Path,\n\n        [string]$TopologyFile,\n\n        [switch]$IncludeFallbackRetailServiceModels,\n\n        [switch]$ForceFallbackServiceModels\n    )\n\n    if (-not $TopologyFile) {\n        $topologyFile = Join-Path $Path 'DefaultTopologyData.xml'\n    }\n\n    Write-PSFMessage -Level Verbose \"Updating topology file: $topologyFile\"\n\n    [xml]$xml = Get-Content $topologyFile\n    $machine = $xml.TopologyData.MachineList.Machine\n    $machine.Name = $env:computername\n\n    $serviceModelList = $xml.SelectSingleNode(\"//ServiceModelList\")\n    $null = $serviceModelList.RemoveAll()\n\n    $models = Get-InstalledServiceModelNameList -Path $Path\n    $params = @{\n        InstalledModels = $models\n        TopologyFile = $topologyFile\n        IncludeFallbackRetailServiceModels = $IncludeFallbackRetailServiceModels\n        ForceFallbackServiceModels = $ForceFallbackServiceModels\n    }\n    $models = Repair-InstalledServiceModelIssue @params\n\n    foreach ($name in $models) {\n        $element = $xml.CreateElement('string')\n        $element.InnerText = $name\n        $serviceModelList.AppendChild($element)\n    }\n\n    $xml.Save($topologyFile)\n\n    $true\n}\n\nfunction Get-InstalledServiceModelNameList {\n    [CmdletBinding()]\n    [OutputType([System.Collections.ArrayList])]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string]$Path\n    )\n\n    Write-PSFMessage -Level Verbose \"Getting installed service models\"\n\n    $Files2Process = New-Object -TypeName \"System.Collections.ArrayList\"\n    $null = $Files2Process.Add((Join-Path $Path 'Microsoft.Dynamics.AX.AXInstallationInfo.dll'))\n    Import-AssemblyFileIntoMemory -Path $($Files2Process.ToArray())\n\n    $models = [Microsoft.Dynamics.AX.AXInstallationInfo.AXInstallationInfo]::GetInstalledServiceModel()\n    $installedModelNames = $models | ForEach-Object {\n        $_.Name\n     }\n     $installedModelNames\n}\n\nfunction Repair-InstalledServiceModelIssue {\n    [CmdletBinding()]\n    [OutputType([System.Collections.ArrayList])]\n    param (\n        [Parameter(Mandatory = $true)]\n        [string[]]$InstalledModels,\n\n        [string]$TopologyFile,\n\n        [switch]$IncludeFallbackRetailServiceModels,\n\n        [switch]$ForceFallbackServiceModels\n    )\n\n    Write-PSFMessage -Level Verbose \"Handling installed service model issues\"\n\n    $models = $InstalledModels\n    $useFallbackServiceModels = $false\n    $fallbackServiceModels = $Script:FallbackInstallationCoreServiceModelNames\n\n    if ($null -eq $installedModels -or $installedModels.Count -eq 0) {\n        Write-PSFMessage -Level Warning \"No installed service models found.\"\n        $useFallbackServiceModels = $true\n    }\n\n    # Compare models and fallback list of known service model names\n    $fallbackModelsNotInInstalledList = $fallbackServiceModels | Where-Object { $_ -notin $models }\n    if ($fallbackModelsNotInInstalledList.Count -gt 0) {\n        Write-PSFMessage -Level Warning \"The following service models are in the fallback list of known service model names, but not listed as installed: $($fallbackModelsNotInInstalledList -join ', ')\"\n        if ($ForceFallbackServiceModels) {\n            $useFallbackServiceModels = $true\n        }\n        else {\n            Write-PSFMessage -Level Output \"If you want to use the fallback list, please use the -ForceFallbackServiceModels switch.\"\n        }\n    }\n\n    if ($useFallbackServiceModels) {\n        Write-PSFMessage -Level Output \"Using fallback list of known service model names.\"\n        $serviceModelNames = $fallbackServiceModels\n        if ($IncludeFallbackRetailServiceModels) {\n            $serviceModelNames += $Script:FallbackInstallationRetailServiceModelNames\n        }\n        else {\n            Write-PSFMessage -Level Output \"The fallback list of known service model names does not include the retail service models. To include them, use the -IncludeFallbackRetailServiceModels switch. See https://github.com/d365collaborative/d365fo.tools/issues/878 for more information.\"\n        }\n        $models = $serviceModelNames\n    }\n\n    $models\n}"
  },
  {
    "path": "d365fo.tools/internal/misc/AzureDevOps.url",
    "content": "﻿[DEFAULT]\nBASEURL=##URL##\n[{000214A0-0000-0000-C000-000000000046}]\nProp3=19,11\n[InternetShortcut]\nIDList=\nURL=##URL##\nIconFile=https://cdn.vsassets.io/content/icons/favicon.ico\nIconIndex=1\n"
  },
  {
    "path": "d365fo.tools/internal/misc/Bookmarks",
    "content": "{\n   \"checksum\": \"a38a604289a5cdc83c5a0397d18a310e\",\n   \"roots\": {\n      \"bookmark_bar\": {\n         \"children\": [],\n         \"guid\": \"0bc5d13f-2cba-5d74-951f-3f233fe6c908\",\n         \"id\": \"1\",\n         \"name\": \"Favourites bar\",\n         \"source\": \"unknown\",\n         \"type\": \"folder\"\n      },\n      \"other\": {\n         \"children\": [],\n         \"guid\": \"82b081ec-3dd3-529c-8475-ab6c344590dd\",\n         \"id\": \"2\",\n         \"name\": \"Other favourites\",\n         \"source\": \"unknown\",\n         \"type\": \"folder\"\n      },\n      \"synced\": {\n         \"children\": [],\n         \"guid\": \"4cf2e351-0e85-532b-bb37-df045d8f8d0f\",\n         \"id\": \"3\",\n         \"name\": \"Mobile favourites\",\n         \"source\": \"unknown\",\n         \"type\": \"folder\"\n      }\n   },\n   \"version\": 1\n}"
  },
  {
    "path": "d365fo.tools/internal/misc/D365FO.url",
    "content": "﻿[DEFAULT]\nBASEURL=##URL##\n[{000214A0-0000-0000-C000-000000000046}]\nProp3=19,11\n[InternetShortcut]\nIDList=\nURL=##URL##\nIconFile=https://lcs.dynamics.com/content/ux/images/365/finops/favicon.ico\nIconIndex=1\n"
  },
  {
    "path": "d365fo.tools/internal/misc/RepairBacpac.Qualifier.json",
    "content": "﻿[\n    {\n        \"Search\": \"*<Element Type=\\\"SqlRoleMembership\\\">*\",\n        \"Qualifier\": \"*<References Name=*ms_db_configwriter*\",\n        \"End\": \"*</Element>*\"\n    },\n    {\n        \"Search\": \"*<Element Type=\\\"SqlRoleMembership\\\">*\",\n        \"Qualifier\": \"*<References Name=*ms_db_configreader*\",\n        \"End\": \"*</Element>*\"\n    }\n]"
  },
  {
    "path": "d365fo.tools/internal/misc/RepairBacpac.Replace.json",
    "content": "﻿[\n    {\n        \"Search\": \"<Property Name=\\\"AutoDrop\\\" Value=\\\"True\\\" />\",\n        \"Replace\": \"\"\n    },\n    {\n        \"Search\": \"<Property Name=\\\"QueryStoreCaptureMode\\\" Value=\\\"4\\\" />\",\n        \"Replace\": \"<Property Name=\\\"QueryStoreCaptureMode\\\" Value=\\\"2\\\" />\"\n    }\n]\n"
  },
  {
    "path": "d365fo.tools/internal/misc/RepairBacpac.Simple.json",
    "content": "﻿[\n    {\n        \"Search\": \"*<Element Type=\\\"SqlPermissionStatement\\\"*ms_db_configreader*\",\n        \"End\": \"*</Element>*\"\n    },\n    {\n        \"Search\": \"*<Element Type=\\\"SqlPermissionStatement\\\"*ms_db_configwriter*\",\n        \"End\": \"*</Element>*\"\n    },\n\t{\n        \"Search\": \"*<Element Type=\\\"SqlPermissionStatement\\\"*KillDatabaseConnection*\",\n        \"End\": \"*</Element>*\"\n    }\n]\n"
  },
  {
    "path": "d365fo.tools/internal/scripts/enums.ps1",
    "content": "﻿enum EnvironmentType {\n    Unknown\n    LocalHostedTier1\n    AzureHostedTier1\n    MSHostedTier1\n    MSHostedTier2\n}\n\nenum ServerRole {\n    Unknown\n    Development\n    Demo\n    Build\n    AOS\n    BI\n}\n\nenum LcsAssetFileType {\n    Model = 1\n    ProcessDataPackage = 4\n    SoftwareDeployablePackage = 10\n    GERConfiguration = 12\n    DataPackage = 15\n    PowerBIReportModel = 19\n    ECommercePackage = 26\n    NuGetPackage = 27\n    RetailSelfServicePackage = 28\n    CommerceCloudScaleUnitExtension = 29\n}"
  },
  {
    "path": "d365fo.tools/internal/scripts/license.ps1",
    "content": "﻿New-PSFLicense -Product 'd365fo.tools' -Manufacturer 'Motz' -ProductVersion $script:ModuleVersion -ProductType Module -Name MIT -Version \"1.0.0.0\" -Date (Get-Date \"2018-09-20\") -Text @\"\nCopyright (c) 2018 Motz\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\"@"
  },
  {
    "path": "d365fo.tools/internal/scripts/load-dotnet-assemblies.ps1",
    "content": "﻿# Add the System.Web type\nAdd-Type -AssemblyName System.Web\n\n# Add the System.Net.Http type\nAdd-Type -AssemblyName System.Net.Http\n\n# Add the System.IO.Compression type\nAdd-Type -AssemblyName System.IO.Compression\n\n# Add the System.IO.Compression.FileSystem type\nAdd-Type -AssemblyName System.IO.Compression.FileSystem"
  },
  {
    "path": "d365fo.tools/internal/scripts/postimport.ps1",
    "content": "﻿# Add all things you want to run after importing the main code\n\n# Load Configurations\nforeach ($file in (Get-ChildItem \"$ModuleRoot\\internal\\configurations\\*.ps1\" -ErrorAction Ignore)) {\n\t. Import-ModuleFile -Path $file.FullName\n}\n\n# Load Tab Expansion\nforeach ($file in (Get-ChildItem \"$ModuleRoot\\internal\\tepp\\*.tepp.ps1\" -ErrorAction Ignore)) {\n\t. Import-ModuleFile -Path $file.FullName\n}\n\n# Load Tab Expansion Assignment\n. Import-ModuleFile -Path \"$ModuleRoot\\internal\\tepp\\assignment.ps1\"\n\n# Load License\n. Import-ModuleFile -Path \"$ModuleRoot\\internal\\scripts\\license.ps1\"\n\n# Load Variables\n. Import-ModuleFile -Path \"$ModuleRoot\\internal\\scripts\\variables.ps1\"\n\n# Load dot net assemblies\n. Import-ModuleFile -Path \"$ModuleRoot\\internal\\scripts\\load-dotnet-assemblies.ps1\""
  },
  {
    "path": "d365fo.tools/internal/scripts/preimport.ps1",
    "content": "﻿# Add all things you want to run before importing the main code\n \n# Load Enums\n. Import-ModuleFile -Path \"$ModuleRoot\\internal\\scripts\\enums.ps1\"\n"
  },
  {
    "path": "d365fo.tools/internal/scripts/variables.ps1",
    "content": "﻿$Script:TimeSignals = @{ }\n\nWrite-PSFMessage -Level Verbose -Message \"Gathering all variables to assist the different cmdlets to function\"\n\n$serviceDrive = ($env:ServiceDrive) -replace \" \", \"\"\n\n# When a local Tier1 machine is domain joined, the domain users will not have the %ServiceDrive% environment variable\nif ([system.string]::IsNullOrEmpty($serviceDrive)) {\n    $serviceDrive = \"c:\"\n\n    Write-PSFMessage -Level Host -Message \"Unable to locate the %ServiceDrive% environment variable. It could indicate that the machine is either not configured with D365FO or that you have domain joined a local Tier1. We have defaulted to <c='em'>c:\\</c>\"\n    Write-PSFMessage -Level Host -Message \"This message will show every time you load the module. If you want to silence this message, please add the ServiceDrive environment variable by executing this command (remember to restart the console afterwards):\"\n    Write-PSFHostColor -String '<c=\"em\">[Environment]::SetEnvironmentVariable(\"ServiceDrive\", \"C:\", \"Machine\")</c>'\n}\n\n$script:ServiceDrive = $serviceDrive\n\n$Script:IsAdminRuntime = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)\n\n$Script:WebConfig = \"web.config\"\n\n$Script:DevConfig = \"DynamicsDevConfig.xml\"\n\n$Script:WifConfig = \"wif.config\"\n\n$Script:WifServicesConfig = \"wif.services.config\"\n\n$Script:Hosts = 'C:\\Windows\\System32\\drivers\\etc\\hosts'\n\n$Script:DefaultAOSName = 'usnconeboxax1aos'\n\n$Script:IISHostFile = 'C:\\Windows\\System32\\inetsrv\\Config\\applicationHost.config'\n\n$Script:MRConfigFile = 'C:\\FinancialReporting\\Server\\ApplicationService\\bin\\MRServiceHost.settings.config'\n\n#Update all module variables\nUpdate-ModuleVariables\n\n# Environment variables\n$environment = Get-ApplicationEnvironment\n\n$Script:TenantId = $environment.Aad.TenantDomainGUID\n\n$aos = $environment.Aos\n$Script:AOSPath = $aos.AppRoot\n$Script:PackageDirectory = $aos.PackageDirectory\n$Script:MetaDataDir = $aos.MetadataDirectory\n\n$dataAccess = $environment.DataAccess\n$Script:DatabaseServer = $dataAccess.DbServer\n$Script:DatabaseName = $dataAccess.Database\n$Script:DatabaseUserName = $dataAccess.SqlUser\n$Script:DatabaseUserPassword = $dataAccess.SqlPwd\n\n$common = $environment.Common\n$Script:BinDir = $common.BinDir\n$Script:BinDirTools = $common.DevToolsBinDir\n$Script:IsOnebox = $common.IsOneboxEnvironment\n\n$Script:ServerRole = [ServerRole]::Unknown\n$RoleVaule = $(\n    If ($environment.Monitoring.MARole -eq \"\" -or $environment.Monitoring.MARole -eq \"dev\") {\n        \"Development\"\n    } Else {\n        $environment.Monitoring.MARole\n    }\n)\nif ($null -ne $RoleVaule) {\n    $Script:ServerRole = [ServerRole][Enum]::Parse([type]\"ServerRole\", $RoleVaule, $true);\n}\n\n$infrastructure = $environment.Infrastructure\n$Script:EnvironmentType = [EnvironmentType]::Unknown\n$Script:CanUseTrustedConnection = $false\nif ($infrastructure.HostName -like \"*cloud.onebox.dynamics.com*\") {\n    $Script:EnvironmentType = [EnvironmentType]::LocalHostedTier1\n    $Script:CanUseTrustedConnection = $true\n}\nelseif ($infrastructure.HostName -match \"(cloudax|axcloud).*dynamics.com\") {\n    $Script:EnvironmentType = [EnvironmentType]::AzureHostedTier1\n    $Script:CanUseTrustedConnection = $true\n}\nelseif ($infrastructure.HostName -like \"*sandbox.ax.dynamics.com*\") {\n    $Script:EnvironmentType = [EnvironmentType]::MSHostedTier1\n    $Script:CanUseTrustedConnection = $true\n}\nelseif ($infrastructure.HostName -like \"*sandbox.operations.*dynamics.com*\") {\n    $Script:EnvironmentType = [EnvironmentType]::MSHostedTier2\n}\n$Script:Url = $infrastructure.HostUrl\n\n$Script:Company = \"DAT\"\n\n\n$RegSplat = @{\n    Path = \"HKLM:\\SOFTWARE\\Microsoft\\Dynamics\\Deployment\\\"\n    Name = \"InstallationInfoDirectory\"\n}\n\n$RegValue = $( if (Test-RegistryValue @RegSplat) { Join-Path (Get-ItemPropertyValue @RegSplat) \"InstallationRecords\" } else { \"\" } )\n$Script:InstallationRecordsDir = $RegValue\n\n# On a local VHD, the information about the installed service models may not be available.\n# As a fallback, this list of known service model names may be used.\n$Script:FallbackInstallationCoreServiceModelNames = @(\n    \"ALMService\",\n    \"AOSService\",\n    \"BIService\",\n    \"DevToolsService\",\n    \"DIXFService\",\n    \"MROneBox\",\n    \"PerfSDK\",\n    \"ReportingService\"\n)\n# Starting with version 10.0.41, Microsoft has released VHD images without the retail components\n# preinstalled. The retail components are only included in the fallback list if the user\n# explicitly requests it.\n$Script:FallbackInstallationRetailServiceModelNames = @(\n    \"RetailCloudPos\",\n    \"RetailHQConfiguration\",\n    \"RetailSDK\",\n    \"RetailSelfService\",\n    \"RetailServer\"\n)\n\n$Script:UserIsAdmin = $env:UserName -like \"*admin*\"\n\n$Script:TfDir = \"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\\"\n\n$Script:SQLTools = \"C:\\Program Files (x86)\\Microsoft SQL Server\\130\\Tools\\Binn\"\n\n$Script:SSRSTools = \"C:\\Program Files\\Microsoft SQL Server Reporting Services\\Shared Tools\"\n\n$Script:DefaultTempPath = \"c:\\temp\\d365fo.tools\"\n\nforeach ($item in (Get-PSFConfig -FullName d365fo.tools.active*)) {\n    $nameTemp = $item.FullName -replace \"^d365fo.tools.\", \"\"\n    $name = ($nameTemp -Split \"\\.\" | ForEach-Object { (Get-Culture).TextInfo.ToTitleCase($_) } ) -Join \"\"\n\n    New-Variable -Name $name -Value $item.Value -Scope Script\n}\n\n#Active LCS Upload config extraction\nUpdate-LcsApiVariables\n\n$maskOutput = @(\n    \"AccessToken\",\n    \"AzureStorageAccessToken\",\n    \"Token\",\n    \"BearerToken\",\n    \"Password\",\n    \"RefreshToken\",\n    \"SAS\"\n    \"AzureStorageSAS\"\n)\n\n#Active broadcast message config extraction\nUpdate-BroadcastVariables\n\n#Update different PSF Configuration variables values\nUpdate-PsfConfigVariables\n\n#Active Azure Storage Configuration variables values\nUpdate-AzureStorageVariables\n\n(Get-Variable -Scope Script) | ForEach-Object {\n    $val = $null\n\n    if ($maskOutput -contains $($_.Name)) {\n        $val = \"The variable was found - [...REDACTED...]\"\n    }\n    else {\n        $val = $($_.Value)\n    }\n\n    Write-PSFMessage -Level Verbose -Message \"$($_.Name) - $val\" -Target $val -FunctionName \"Variables.ps1\"\n}\n\nWrite-PSFMessage -Level Verbose -Message \"Finished outputting all the variable content.\""
  },
  {
    "path": "d365fo.tools/internal/sql/add-aadapplicationintod365fo.sql",
    "content": "﻿\n/*Variable input @Name,@UserId,@ClientId */\n\nINSERT INTO SYSAADCLIENTTABLE (NAME, USERID, AADCLIENTID)\nVALUES (@Name, @UserId, @ClientId)"
  },
  {
    "path": "d365fo.tools/internal/sql/add-aaduserintod365fo.sql",
    "content": "﻿\n/*Variable input @Id,@SignInName,@Name,@SID, @StartUpCompany, @NetworkDomain, @IdentityProvider */\n\nDROP TABLE IF EXISTS #TempUser\n\nSET Nocount ON;\n\nDECLARE @TableId AS int,\n        @RecId AS bigint,\n\t\t@ExistsCompany as int\n\nSELECT @ExistsCompany = count(1)\nFROM [dbo].[DIRPARTYTABLE]\n  join dbo.[PARTITIONS] p on p.RECID = DIRPARTYTABLE.PARTITION\nwhere DATAAREA = @StartUpCompany\n\nif(@ExistsCompany = 0)\n\tset @StartUpCompany ='dat'\n\n/* Get Admin to copy */\nSELECT top 1\n  userInfo.*\nINTO #TempUser\nFROM userinfo\n  JOIN [PARTITIONS] ON [PARTITIONS].Recid = userinfo.PARTITION\nWHERE id = 'admin'\n  AND PARTITIONKEY = 'initial'\n\n\n/*Change row to match the new user */\nUPDATE #TempUser\n  SET\n    -- [RECID] = @RecId\t  ,\n    [ID] = @Id\n\t  ,[Name] = @Name\n\t  ,[SID] = @SID\n\t  ,[COMPANY] = @StartUpCompany\n    ,[NETWORKALIAS] = @SignInName\n\t  ,RECVERSION = 1\n    ,[NETWORKDOMAIN] = @NetworkDomain\n    ,[IDENTITYPROVIDER] = @IdentityProvider\n    ,[OBJECTID] = iif(@ObjectId = '',[OBJECTID],@ObjectId)\n    ,[EXTERNALID] = ''\n    ,[LANGUAGE] = iif(@Language = '',[LANGUAGE],@Language)\n\n\n/* Create the user */\n\nINSERT INTO userinfo\n  (ID, NAME, ENABLE, DEL_STARTUPMENU, STATUSLINEINFO, TOOLBARINFO, DEBUGINFO, AUTOINFO, AUTOUPDATE, GARBAGECOLLECTLIMIT, HISTORYLIMIT, MESSAGELIMIT, GENERALINFO, SHOWSTATUSLINE, SHOWTOOLBAR, DEBUGGERPOPUP, SHOWAOTLAYER, DEL_PASSWORD, DEL_OSACCOUNTNAME, STARTUPPROJECT, CONFIRMDELETE, CONFIRMUPDATE, REPORTFONTNAME, REPORTFONTSIZE, FORMFONTNAME, FORMFONTSIZE, PROPERTYFONTNAME, PROPERTYFONTSIZE, INFOLOGLEVEL, COMPANY, AUTOLOGOFF, QUERYTIMELIMIT, TRACEINFO, REPORTTOPMARGIN, REPORTBOTTOMMARGIN, REPORTLEFTMARGIN, REPORTRIGHTMARGIN, COMPILERWARNINGLEVEL, SID, NETWORKDOMAIN, NETWORKALIAS, ENABLEDONCE, EXTERNALUSER, LANGUAGE, HELPLANGUAGE, PREFERREDTIMEZONE, PREFERREDCALENDAR, HOMEPAGEREFRESHDURATION, NOTIFYTIMEZONEMISMATCH, FILTERBYGRIDONBYDEFAULT, GLOBALFORMOPENMODE, DEL_DEFAULTMODELID, SHOWMODELNAMEINAOT, ACCOUNTTYPE, ISSUERRECID, CREDENTIALRECID, GLOBALLISTPAGELINKMODE, GLOBALEXCELEXPORTMODE, CLIENTACCESSLOGLEVEL, DEFAULTPARTITION, GLOBALEXCELEXPORTFILEPATH, EXTERNALIDTYPE, EXTERNALID, RECVERSION, PARTITION, PREFERREDLOCALE, IDENTITYPROVIDER, OBJECTID, INTERACTIVELOGON, ISMICROSOFTACCOUNT)\nSELECT ID, NAME, ENABLE, DEL_STARTUPMENU, STATUSLINEINFO, TOOLBARINFO, DEBUGINFO, AUTOINFO, AUTOUPDATE, GARBAGECOLLECTLIMIT, HISTORYLIMIT, MESSAGELIMIT, GENERALINFO, SHOWSTATUSLINE, SHOWTOOLBAR, DEBUGGERPOPUP, SHOWAOTLAYER, DEL_PASSWORD, DEL_OSACCOUNTNAME, STARTUPPROJECT, CONFIRMDELETE, CONFIRMUPDATE, REPORTFONTNAME, REPORTFONTSIZE, FORMFONTNAME, FORMFONTSIZE, PROPERTYFONTNAME, PROPERTYFONTSIZE, INFOLOGLEVEL, COMPANY, AUTOLOGOFF, QUERYTIMELIMIT, TRACEINFO, REPORTTOPMARGIN, REPORTBOTTOMMARGIN, REPORTLEFTMARGIN, REPORTRIGHTMARGIN, COMPILERWARNINGLEVEL, SID, NETWORKDOMAIN, NETWORKALIAS, ENABLEDONCE, EXTERNALUSER, LANGUAGE, HELPLANGUAGE, PREFERREDTIMEZONE, PREFERREDCALENDAR, HOMEPAGEREFRESHDURATION, NOTIFYTIMEZONEMISMATCH, FILTERBYGRIDONBYDEFAULT, GLOBALFORMOPENMODE, DEL_DEFAULTMODELID, SHOWMODELNAMEINAOT, ACCOUNTTYPE, ISSUERRECID, CREDENTIALRECID, GLOBALLISTPAGELINKMODE, GLOBALEXCELEXPORTMODE, CLIENTACCESSLOGLEVEL, DEFAULTPARTITION, GLOBALEXCELEXPORTFILEPATH, EXTERNALIDTYPE, EXTERNALID, RECVERSION, PARTITION, PREFERREDLOCALE, IDENTITYPROVIDER, OBJECTID, INTERACTIVELOGON, ISMICROSOFTACCOUNT\nFROM #TempUser\n\nDROP TABLE #TempUser\n\nSET Nocount OFF;\nselect count(1)\nfrom userinfo\nwhere [RECID] = (SELECT MAX(Recid)\nFROM dbo.USERINFO)"
  },
  {
    "path": "d365fo.tools/internal/sql/add-bacpacdatabase.sql",
    "content": "﻿Declare @BackupTo as varchar(404) = @BackupDirectory + '\\' + @NewName + '.bak'\nDeclare @BackupName as varchar(150) = @NewName + 'Bacpac full database backup'\nDeclare @BackupCommand as varchar(1000)\n\nset @BackupCommand = 'BACKUP DATABASE ['  + @CurrentDatabase + '] TO  DISK = '''  + @BackupTo + ''' WITH NOFORMAT, INIT,  NAME = ''' + @BackupName + ''', SKIP, NOREWIND, NOUNLOAD,  STATS = 10'\nexec (@BackupCommand)\n\nDeclare @MoveCommand as nvarchar(1000)\nDeclare @MoveResult as nvarchar(1000)\n\nSELECT  @MoveCommand =  'select @MoveResult = STUFF(( select '',Move '''''' + name + '''''' to '''''' +  LEFT([filename],LEN([filename]) - charindex(''\\'',reverse([filename]),1) + 1) +''' + @NewName + ''' + RIGHT([filename], CHARINDEX(''.'', REVERSE([filename]))) +'''''''' from sys.sysfiles FOR XML PATH('''')), 1, 1, '''')'\nexec sp_executesql  @MoveCommand,N'@MoveResult varchar(1000) output',@MoveResult output\n\nDeclare @RestoreCommand as varchar(4000)\n\nset  @RestoreCommand =  ' RESTORE DATABASE [' + @NewName + '] FROM  DISK = ''' + @BackupTo + ''' WITH  FILE = 1, ' + @MoveResult + ',  NOUNLOAD,  STATS = 5'\n              \nexec (@RestoreCommand)\n\n--File should be obsolute"
  },
  {
    "path": "d365fo.tools/internal/sql/backuprestoredb.sql",
    "content": "﻿Declare @BackupTo as varchar(404) = @BackupDirectory + '\\' + @NewName + '.bak'\nDeclare @BackupName as varchar(150) = @NewName + 'Bacpac full database backup'\nDeclare @BackupCommand as varchar(1000)\n\nset @BackupCommand = 'BACKUP DATABASE ['  + @CurrentDatabase + '] TO  DISK = '''  + @BackupTo + ''' WITH COPY_ONLY, COMPRESSION, NOFORMAT, INIT,  NAME = ''' + @BackupName + ''', SKIP, NOREWIND, NOUNLOAD,  STATS = 10'\nexec (@BackupCommand)\n\nDeclare @MoveCommand as nvarchar(1000)\nDeclare @MoveResult as nvarchar(1000)\n\nSELECT  @MoveCommand =  'select @MoveResult = STUFF(( select '',Move '''''' + name + '''''' to '''''' +  LEFT([filename],LEN([filename]) - charindex(''\\'',reverse([filename]),1) + 1) +''' + @NewName + ''' + RIGHT([filename], CHARINDEX(''.'', REVERSE([filename]))) +'''''''' from sys.sysfiles FOR XML PATH('''')), 1, 1, '''')'\nexec sp_executesql  @MoveCommand,N'@MoveResult varchar(1000) output',@MoveResult output\n\nDeclare @RestoreCommand as varchar(4000)\n\nset  @RestoreCommand =  ' RESTORE DATABASE [' + @NewName + '] FROM  DISK = ''' + @BackupTo + ''' WITH  FILE = 1, ' + @MoveResult + ',  NOUNLOAD,  REPLACE, STATS = 5'\n              \nexec (@RestoreCommand)\n"
  },
  {
    "path": "d365fo.tools/internal/sql/checkfornewazuredb.sql",
    "content": "﻿SELECT session_activity_id FROM sys.dm_operation_status WHERE major_resource_id = @NewName AND operation = 'TERMINATE CONTINUOUS DATABASE COPY' AND state = 2 AND Start_time > @Time;"
  },
  {
    "path": "d365fo.tools/internal/sql/clear-azurebacpacdatabase.sql",
    "content": "﻿--Author: Rasmus Andersen (@ITRasmus)\n--Author: Charles Colombel (@dropshind)\n--Author: Tommy Skaue (@skaue)\n--Prepare a database in Azure SQL Database for export to SQL Server.\n-- Re-assign full text catalogs to [dbo]\nBEGIN\n    DECLARE @catalogName NVARCHAR(256);\n    DECLARE @sqlStmtTable NVARCHAR(512)\n    DECLARE reassignfulltextcatalogcursor CURSOR FOR\n      SELECT DISTINCT NAME\n      FROM   sys.fulltext_catalogs\n\n    -- Open cursor and disable on all tables returned\n    OPEN reassignfulltextcatalogcursor\n\n    FETCH next FROM reassignfulltextcatalogcursor INTO @catalogName\n\n    WHILE @@FETCH_STATUS = 0\n      BEGIN\n          SET @sqlStmtTable = 'ALTER AUTHORIZATION ON Fulltext Catalog::['\n                              + @catalogName + '] TO [dbo]'\n\n          EXEC Sp_executesql\n            @sqlStmtTable\n\n          FETCH next FROM reassignfulltextcatalogcursor INTO @catalogName\n      END\n\n    CLOSE reassignfulltextcatalogcursor\n\n    DEALLOCATE reassignfulltextcatalogcursor\nEND\n\n--Disable change tracking on tables where it is enabled.\nDECLARE @SQL VARCHAR(1000)\n\nSET quoted_identifier OFF\n\nDECLARE changetrackingcursor CURSOR FOR\n  SELECT 'ALTER TABLE [' + t.NAME\n         + '] DISABLE CHANGE_TRACKING'\n  FROM   sys.change_tracking_tables ct\n         INNER JOIN sys.tables t\n                 ON ct.object_id = t.object_id\n\nOPEN changetrackingcursor\n\nFETCH changetrackingcursor INTO @SQL\n\nWHILE @@Fetch_Status = 0\n  BEGIN\n      EXEC(@SQL)\n\n      FETCH changetrackingcursor INTO @SQL\n  END\n\nCLOSE changetrackingcursor\n\nDEALLOCATE changetrackingcursor\n\n--Disable change tracking on the database itself.\nIF( 1 = (SELECT 1\n         FROM   sys.change_tracking_databases\n         WHERE  database_id = Db_id('@NewDatabase')) )\n  ALTER DATABASE\n  -- SET THE NAME OF YOUR DATABASE BELOW\n  [@NewDatabase]\n\nSET change_tracking = OFF\n\n-- Ensure users can be dropped by changing ownership of certain schemas\nDECLARE @SCHEMASQL VARCHAR(1000)\n\nSET quoted_identifier OFF\n\nDECLARE schemacursor CURSOR FOR\n  SELECT 'ALTER AUTHORIZATION ON SCHEMA::[' + NAME\n         + '] TO [DBO]; '\n  FROM   sys.schemas\n  WHERE  sys.schemas.NAME IN ( 'BACKUP', 'SHADOW', 'BatchScheduling' )\n\nOPEN schemacursor\n\nFETCH schemacursor INTO @SCHEMASQL\n\nWHILE @@FETCH_STATUS = 0\n  BEGIN\n      EXEC(@SCHEMASQL)\n\n      FETCH schemacursor INTO @SCHEMASQL\n  END\n\nCLOSE schemacursor\n\nDEALLOCATE schemacursor\n\n--Drop certificates that are tied to database users, which will cause errors when exporting the database\n--if not dropped because then the corresponding user(s) can't be dropped later in the script.\n--These certs are created from User options > Account > Electronic signature > \"Get certificate\" button in D365FO UI\nDECLARE certcursor CURSOR FOR\n  SELECT 'DROP CERTIFICATE ' + Quotename(c.NAME) + ';'\n  FROM   sys.certificates c\n  WHERE  c.principal_id IN (SELECT u.uid\n                            FROM   sys.sysusers u\n                            WHERE  issqlrole = 0\n                                   AND hasdbaccess = 1\n                                   AND NAME <> 'dbo');\n\nOPEN certcursor;\n\nFETCH certcursor INTO @SQL;\n\nWHILE @@Fetch_Status = 0\n  BEGIN\n      EXEC(@SQL);\n\n      FETCH certcursor INTO @SQL;\n  END;\n\nCLOSE certcursor;\n\nDEALLOCATE certcursor;\n\n--Remove the database level users from the database\n--these will be recreated after importing in SQL Server.\nDECLARE @userSQL VARCHAR(1000)\n\nSET quoted_identifier OFF\n\nDECLARE usercursor CURSOR FOR\n  SELECT 'DROP USER [' + NAME + ']'\n  FROM   sys.sysusers\n  WHERE  issqlrole = 0\n         AND hasdbaccess = 1\n         AND NAME <> 'dbo'\n\nOPEN usercursor\n\nFETCH usercursor INTO @userSQL\n\nWHILE @@Fetch_Status = 0\n  BEGIN\n      EXEC(@userSQL)\n\n      FETCH usercursor INTO @userSQL\n  END\n\nCLOSE usercursor\n\nDEALLOCATE usercursor\n\n--Delete the SYSSQLRESOURCESTATSVIEW view as it has an Azure-specific definition in it.\n--We will run db synch later to recreate the correct view for SQL Server.\nIF( 1 = (SELECT 1\n         FROM   sys.views\n         WHERE  NAME = 'SYSSQLRESOURCESTATSVIEW') )\n  DROP VIEW syssqlresourcestatsview\n\n--Next, set system parameters ready for being a SQL Server Database.\nUPDATE sysglobalconfiguration\nSET    value = 'SQLSERVER'\nWHERE  NAME = 'BACKENDDB'\n\nUPDATE sysglobalconfiguration\nSET    value = 0\nWHERE  NAME = 'TEMPTABLEINAXDB'\n\n--Clean up the batch server configuration, server sessions, and printers from the previous environment.\nTRUNCATE TABLE sysserverconfig\n\nTRUNCATE TABLE sysserversessions\n\nTRUNCATE TABLE syscorpnetprinters\n\nTRUNCATE TABLE sysclientsessions\n\nTRUNCATE TABLE batchserverconfig\n\nTRUNCATE TABLE batchservergroup\n\n--Remove records which could lead to accidentally sending an email externally.\nUPDATE sysemailparameters\nSET    smtprelayservername = '',\n       mailernoninteractive = 'SMTP'\n\n--LANE.SWENKA 9/12/18 Forcing SMTP as Exchange provider can still email on refresh\n--Remove encrypted SMTP Password record(s)\nTRUNCATE TABLE sysemailsmtppassword; --GO\n\nUPDATE logisticselectronicaddress\nSET    locator = ''\nWHERE  locator LIKE '%@%'; --GO\n\nTRUNCATE TABLE printmgmtsettings\n\nTRUNCATE TABLE printmgmtdocinstance\n\n--Set any waiting, executing, ready, or canceling batches to withhold.\nUPDATE batchjob\nSET    status = 0\nWHERE  status IN ( 1, 2, 5, 7 ); --GO\n\n-- Clear encrypted hardware profile merchand properties\nUPDATE dbo.retailhardwareprofile\nSET    securemerchantproperties = NULL\nWHERE  securemerchantproperties IS NOT NULL\n\n--BELOW code is used to handle FULLTEXT INDEX / FULLTEST STOPLIST.\n--Provided by Paul Heisterkamp (Twitter - @braul)\nDECLARE @_SQL NVARCHAR(4000)\n\n-------------------------------------------------------------------------------------\n-- ALTER FULLTEXT INDEX ON [TableName] SET STOPLIST = SYSTEM'\nIF Object_id('tempdb..#TMPSETSTOPLIST') IS NOT NULL\n  DROP TABLE #tmpsetstoplist;\n\nCREATE TABLE #tmpsetstoplist\n  (\n     tablename [NVARCHAR] (250)\n  );\n\nDECLARE cur CURSOR FOR\n  SELECT Object_name(sys.fulltext_indexes.object_id) AS TableName\n  FROM   sys.fulltext_indexes\n  WHERE  stoplist_id != 0\n\nOPEN cur;\n\nDECLARE @TableName [NVARCHAR](250);\n\nFETCH next FROM cur INTO @TableName;\n\nWHILE @@FETCH_STATUS = 0\n  BEGIN\n      INSERT INTO #tmpsetstoplist\n                  (tablename)\n      VALUES      (@TableName);\n\n      FETCH next FROM cur INTO @TableName;\n  END;\n\nCLOSE cur;\n\nDEALLOCATE cur;\n\nDECLARE cur CURSOR FOR\n  SELECT tablename\n  FROM   #tmpsetstoplist;\n\nOPEN cur;\n\nFETCH next FROM cur INTO @TableName;\n\nWHILE @@FETCH_STATUS = 0\n  BEGIN\n      SET @_SQL = N'ALTER FULLTEXT INDEX ON '\n                  + Quotename(@TableName)\n                  + ' SET STOPLIST = SYSTEM'\n\n      PRINT ( @_SQL )\n\n      EXEC Sp_executesql\n        @_SQL\n\n      FETCH next FROM cur INTO @TableName;\n  END;\n\nCLOSE cur;\n\nDEALLOCATE cur;\n\n-------------------------------------------------------------------------------------\n-- DROP FULLTEXT STOPLIST [FullTextStopListName];\nIF Object_id('tempdb..#DROPFULLTEXTSTOPLIST') IS NOT NULL\n  DROP TABLE #dropfulltextstoplist;\n\nCREATE TABLE #dropfulltextstoplist\n  (\n     stoplistname [NVARCHAR] (250)\n  );\n\nDECLARE cur CURSOR FOR\n  SELECT NAME\n  FROM   sys.fulltext_stoplists\n\nOPEN cur;\n\nDECLARE @StopListName [NVARCHAR](250);\n\nFETCH next FROM cur INTO @StopListName;\n\nWHILE @@FETCH_STATUS = 0\n  BEGIN\n      INSERT INTO #dropfulltextstoplist\n                  (stoplistname)\n      VALUES      (@StopListName);\n\n      FETCH next FROM cur INTO @StopListName;\n  END;\n\nCLOSE cur;\n\nDEALLOCATE cur;\n\nDECLARE cur CURSOR FOR\n  SELECT stoplistname\n  FROM   #dropfulltextstoplist;\n\nOPEN cur;\n\nFETCH next FROM cur INTO @StopListName;\n\nWHILE @@FETCH_STATUS = 0\n  BEGIN\n      SET @_SQL = N'DROP FULLTEXT STOPLIST '\n                  + Quotename(@StopListName) + ';'\n\n      PRINT ( @_SQL )\n\n      EXEC Sp_executesql\n        @_SQL\n\n      FETCH next FROM cur INTO @StopListName;\n  END;\n\nCLOSE cur;\n\nDEALLOCATE cur;"
  },
  {
    "path": "d365fo.tools/internal/sql/clear-d365tempdbtables.sql",
    "content": "﻿--Create a cursor.\nDECLARE cur CURSOR\nFOR\nSELECT O.NAME\nFROM\n\tSYS.OBJECTS AS O WITH (NOLOCK),\n\tSYS.SCHEMAS AS S WITH (NOLOCK)\nWHERE S.NAME = 'DBO'\n\tAND S.SCHEMA_ID = O.SCHEMA_ID\n\tAND O.TYPE = 'U'\n\tAND O.NAME LIKE 'T[0-9]%'\n\tand O.create_date < GETDATE() - @Days\n\t\nOPEN cur;\nDECLARE @TableName [nvarchar](250);\n\t\n-- Fetch first record\nFETCH NEXT\nFROM cur\nINTO @TableName;\n\n-- Loop all records\nWHILE @@FETCH_STATUS = 0\nBEGIN\n\tDECLARE @_SQL NVARCHAR(4000)\n\tSET @_SQL = N'DROP TABLE ' + QUOTENAME(@TableName)\n\tPRINT (@_SQL)\n\tEXEC SP_EXECUTESQL @_SQL\n\t \n\t-- Fetch next record\n\tFETCH NEXT\n\tFROM cur\n\tINTO @TableName;\n\nEND;\n\nCLOSE cur;\nDEALLOCATE cur;"
  },
  {
    "path": "d365fo.tools/internal/sql/clear-sqlbacpacdatabase.sql",
    "content": "﻿\nupdate sysglobalconfiguration\nset value = 'SQLAZURE'\nwhere name = 'BACKENDDB'\n\nupdate sysglobalconfiguration\nset value = 1\nwhere name = 'TEMPTABLEINAXDB'\n\ndrop procedure if exists XU_DisableEnableNonClusteredIndexes\ndrop procedure if exists SP_ConfigureTablesForChangeTracking\ndrop procedure if exists SP_ConfigureTablesForChangeTracking_V2\n\nIF  EXISTS(SELECT name FROM sys.schemas WHERE name = 'NT AUTHORITY\\NETWORK SERVICE')\nBEGIN\n\tdrop schema [NT AUTHORITY\\NETWORK SERVICE]\nEND\n\n\nIF DATABASE_PRINCIPAL_ID('NT AUTHORITY\\NETWORK SERVICE') IS NOT NULL\nBEGIN\n    drop user [NT AUTHORITY\\NETWORK SERVICE]\nEND\n\nIF DATABASE_PRINCIPAL_ID('axdbadmin') IS NOT NULL\nBEGIN\n    drop user axdbadmin\nEND\n\nIF DATABASE_PRINCIPAL_ID('axdeployuser') IS NOT NULL\nBEGIN\n    drop user axdeployuser\nEND\n\nIF DATABASE_PRINCIPAL_ID('axmrruntimeuser') IS NOT NULL\nBEGIN\n    drop user axmrruntimeuser\nEND\n\nIF DATABASE_PRINCIPAL_ID('axretaildatasyncuser') IS NOT NULL\nBEGIN\n    drop user axretaildatasyncuser\nEND\n\nIF DATABASE_PRINCIPAL_ID('axretailruntimeuser') IS NOT NULL\nBEGIN\n    drop user axretailruntimeuser\nEND\n\nIF DATABASE_PRINCIPAL_ID('axdeployextuser') IS NOT NULL\nBEGIN\n    drop user axdeployextuser\nEND\n;\n\nDROP USER IF EXISTS [axdbreadonlyuser];\n\nDISABLE TRIGGER ALL ON dbo.RETAILHARDWAREPROFILE\n-- Clear encrypted hardware profile merchand properties\nupdate dbo.RETAILHARDWAREPROFILE set SECUREMERCHANTPROPERTIES = null where SECUREMERCHANTPROPERTIES is not null\n;\nENABLE TRIGGER ALL ON dbo.RETAILHARDWAREPROFILE\n\n"
  },
  {
    "path": "d365fo.tools/internal/sql/disable-changetracking.sql",
    "content": "﻿USE [@DATABASENAME]\n\n--Disable change tracking on tables where it is enabled.\nDECLARE @SQL VARCHAR(1000)\nSET QUOTED_IDENTIFIER OFF\nDECLARE changeTrackingCursor CURSOR FOR\nSELECT 'ALTER TABLE [' + t.name + '] DISABLE CHANGE_TRACKING'\nFROM sys.change_tracking_tables ct\nINNER JOIN sys.tables t ON ct.object_id = t.object_id\n\nOPEN changeTrackingCursor\nFETCH changeTrackingCursor INTO @SQL\nWHILE @@Fetch_Status = 0\nBEGIN\n\tEXEC(@SQL)\n\tFETCH changeTrackingCursor INTO @SQL\nEND\n\nCLOSE changeTrackingCursor\nDEALLOCATE changeTrackingCursor\n\nIF (1 = (SELECT 1 FROM SYS.CHANGE_TRACKING_DATABASES WHERE DATABASE_ID = DB_ID('@DATABASENAME')))\nBEGIN\n    ALTER DATABASE [@DATABASENAME] SET CHANGE_TRACKING = OFF\nEND"
  },
  {
    "path": "d365fo.tools/internal/sql/disable-flight.sql",
    "content": "﻿/* Variable input @FlightName,@FlightServiceId */\n\nDECLARE \n\t@Enabled AS int,\n\t@RecId AS bigint\n\nSELECT @Enabled = [ENABLED], @RecId = SYSFLIGHTING.RECID\nFROM SYSFLIGHTING\nJOIN [PARTITIONS] ON [PARTITIONS].Recid = SYSFLIGHTING.PARTITION\nWHERE FLIGHTNAME = @FlightName\n  AND PARTITIONKEY = 'initial'\n\nif (@Enabled = 1)\n\tUPDATE SYSFLIGHTING SET ENABLED = 0 WHERE RECID = @RecId\n"
  },
  {
    "path": "d365fo.tools/internal/sql/disable-maintenancemode.sql",
    "content": "﻿--Author: Tommy Skaue (@skaue)\nUPDATE [SQLSYSTEMVARIABLES] SET [VALUE] = 0 WHERE [PARM] = 'CONFIGURATIONMODE'"
  },
  {
    "path": "d365fo.tools/internal/sql/disable-user.sql",
    "content": "﻿DROP TABLE IF EXISTS #usersdisabled\n\nSELECT ID, [NAME], NETWORKALIAS\nINTO #usersdisabled\nFROM userinfo\nwhere NETWORKALIAS like @Email\nand [ENABLE] = 1\n\nupdate userinfo\nset [ENABLE] = 0,RECVERSION = RECVERSION +1\nwhere NETWORKALIAS like @Email\nand [ENABLE] = 1\nAND [Id] <> 'admin'\n\nSELECT ID, [NAME], NETWORKALIAS\nFROM #usersdisabled\n\nDROP TABLE IF EXISTS #usersdisabled"
  },
  {
    "path": "d365fo.tools/internal/sql/enable-changetracking.sql",
    "content": "﻿IF((SELECT 1 FROM SYS.CHANGE_TRACKING_DATABASES WHERE DATABASE_ID = DB_ID('@DATABASENAME')) IS NULL)\nBEGIN\n    ALTER DATABASE [@DATABASENAME] SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 6 DAYS, AUTO_CLEANUP = ON)\nEND"
  },
  {
    "path": "d365fo.tools/internal/sql/enable-flight.sql",
    "content": "﻿/* Variable input @FlightName,@FlightServiceId */\n\nDECLARE \n\t@Enabled AS int,\n\t@RecId AS bigint\n\nSELECT @Enabled = [ENABLED], @RecId = SYSFLIGHTING.RECID\nFROM SYSFLIGHTING\nJOIN [PARTITIONS] ON [PARTITIONS].Recid = SYSFLIGHTING.PARTITION\nWHERE FLIGHTNAME = @FlightName\n  AND PARTITIONKEY = 'initial'\n\nif (@Enabled = 1)\n\treturn\nelse if (@Enabled = 0)\n\tUPDATE SYSFLIGHTING SET ENABLED = 1 WHERE RECID = @RecId\nelse\n\tINSERT INTO SYSFLIGHTING (FLIGHTNAME, ENABLED, FLIGHTSERVICEID) VALUES (@FlightName, 1, @FlightServiceId)\n"
  },
  {
    "path": "d365fo.tools/internal/sql/enable-maintenancemode.sql",
    "content": "﻿--Author: Tommy Skaue (@skaue)\nUPDATE [SQLSYSTEMVARIABLES] SET [VALUE] = 1 WHERE [PARM] = 'CONFIGURATIONMODE'"
  },
  {
    "path": "d365fo.tools/internal/sql/enable-user.sql",
    "content": "﻿DROP TABLE IF EXISTS #usersenabled\n\nSELECT ID, [NAME], NETWORKALIAS\nINTO #usersenabled\nFROM userinfo\nwhere NETWORKALIAS like @Email\nand [ENABLE] = 0\n\nupdate userinfo\nset [ENABLE] = 1,RECVERSION = RECVERSION +1\nwhere NETWORKALIAS like @Email\nand [ENABLE] = 0\n\nSELECT ID, [NAME], NETWORKALIAS\nFROM #usersenabled\n\nDROP TABLE IF EXISTS #usersenabled"
  },
  {
    "path": "d365fo.tools/internal/sql/get-alltablefields.sql",
    "content": "﻿SELECT TABLEID AS TableId\n, FIELDID AS FieldId\n, Name AS AotName\n, SQLNAME AS SqlName\nFROM SQLDICTIONARY\nWHERE FIELDID <> 0\nORDER BY FIELDID\n\n"
  },
  {
    "path": "d365fo.tools/internal/sql/get-azureserviceobjective.sql",
    "content": "﻿SELECT  d.name,   \n   slo.edition,slo.service_objective  \nFROM sys.databases d   \nJOIN sys.database_service_objectives slo    \nON d.database_id = slo.database_id"
  },
  {
    "path": "d365fo.tools/internal/sql/get-broadcastmessage.sql",
    "content": "﻿SELECT FROMDATETIME, TODATETIME, AOSID\nFROM SysBroadcastMessage\nORDER BY RECID"
  },
  {
    "path": "d365fo.tools/internal/sql/get-broadcastmessageactive.sql",
    "content": "﻿SELECT FROMDATETIME, TODATETIME, AOSID\nFROM SysBroadcastMessage\nWHERE TODATETIME > GETDATE()\nORDER BY RECID"
  },
  {
    "path": "d365fo.tools/internal/sql/get-database.sql",
    "content": "﻿SELECT name FROM sys.databases\nWHERE NAME NOT IN\n('master', 'model', 'msdb', 'tempdb')\n"
  },
  {
    "path": "d365fo.tools/internal/sql/get-flight.sql",
    "content": "﻿/* Variable input */\n\nSELECT SYSFLIGHTING.*\nFROM SYSFLIGHTING\nJOIN [PARTITIONS] ON [PARTITIONS].Recid = SYSFLIGHTING.PARTITION\nWHERE PARTITIONKEY = 'initial'"
  },
  {
    "path": "d365fo.tools/internal/sql/get-instancevalues.sql",
    "content": "﻿select sscs.[VALUE] as TENANTID,pmt.PLANID,pmt.PLANCAPABILITY from [dbo].[SYSSERVICECONFIGURATIONSETTING]  sscs\njoin [dbo].PROVISIONINGMESSAGETABLE pmt on 1=1\nwhere sscs.[NAME] = 'TENANTID'\n"
  },
  {
    "path": "d365fo.tools/internal/sql/get-maintenancemode.sql",
    "content": "﻿SELECT * FROM [SQLSYSTEMVARIABLES] WHERE [PARM] = 'CONFIGURATIONMODE'"
  },
  {
    "path": "d365fo.tools/internal/sql/get-tablefields.sql",
    "content": "﻿SELECT TABLEID AS TableId\n, FIELDID AS FieldId\n, Name AS AotName\n, SQLNAME AS SqlName\nFROM SQLDICTIONARY\nWHERE TABLEID = @TableId\nAND SHADOW = 0\nORDER BY FIELDID\n\n"
  },
  {
    "path": "d365fo.tools/internal/sql/get-tables.sql",
    "content": "﻿SELECT TABLEID AS TableId\n, Name AS AotName\n, SQLNAME AS SqlName\nFROM SQLDICTIONARY\nWHERE FIELDID = 0\n\n"
  },
  {
    "path": "d365fo.tools/internal/sql/get-tablesequence.sql",
    "content": "﻿SELECT \n--s.object_id AS sequence_object_id,\ns.name AS sequence_name,\nSCHEMA_NAME(oParent.schema_id) +'.'+ oParent.name AS table_name,\n--SCHEMA_NAME(o.schema_id) AS referencing_schema_name,\n--o.name AS referencing_entity_name,\n--dep.referencing_id,\n--dep.referencing_class,\n--dep.referencing_class_desc,\n--dep.is_caller_dependent,\ns.start_value,\ns.increment,\ns.minimum_value,\ns.maximum_value,\ns.is_cached,\ns.cache_size,\ns.current_value\n\nFROM sys.objects AS o\nINNER JOIN sys.sql_expression_dependencies AS dep on dep.referencing_id = o.object_id\nINNER JOIN sys.sequences AS s ON dep.referenced_id = s.object_id\nINNER JOIN sys.objects AS oParent ON o.parent_object_id = oParent.object_id\nWHERE oParent.name LIKE @TableName"
  },
  {
    "path": "d365fo.tools/internal/sql/get-tablesinchangedtracking.sql",
    "content": "﻿USE [@DATABASENAME]\n\nSELECT t.name\nFROM sys.change_tracking_tables ct\nINNER JOIN sys.tables t ON ct.object_id = t.object_id\nORDER BY T.[name]"
  },
  {
    "path": "d365fo.tools/internal/sql/get-user.sql",
    "content": "﻿SELECT\nID\n, [NAME]\n, NETWORKALIAS\n, NETWORKDOMAIN\n, [SID]\n, IDENTITYPROVIDER\n, COMPANY\n, [ENABLE]\nFROM USERINFO\nWHERE NETWORKALIAS LIKE @Email"
  },
  {
    "path": "d365fo.tools/internal/sql/invoke-sphelp.sql",
    "content": "﻿exec sp_help '@schema.@table'"
  },
  {
    "path": "d365fo.tools/internal/sql/newazuredbfromcopy.sql",
    "content": "﻿CREATE DATABASE [@NewName] AS COPY OF [@CurrentDatabase]"
  },
  {
    "path": "d365fo.tools/internal/sql/remove-database.sql",
    "content": "﻿\nDECLARE @kill varchar(8000) = '';\n\nSELECT @kill = @kill + 'KILL ' + CONVERT(varchar(5), c.session_id) + ';'\n\nFROM sys.dm_exec_connections AS c\nJOIN sys.dm_exec_sessions AS s\n    ON c.session_id = s.session_id\nWHERE db_name(database_id) = '@Database' and  c.session_id <> @@SPID\nexec (@kill)\n\nDROP DATABASE [@Database]\n\n--File should be obsolute"
  },
  {
    "path": "d365fo.tools/internal/sql/remove-user.sql",
    "content": "﻿DECLARE @Id NVARCHAR(50)\nSET @Id = (SELECT ID FROM dbo.USERINFO WHERE [NETWORKALIAS] = @Email AND [ID] != 'ADMIN')\n\nDELETE dbo.SECURITYUSERROLE\nWHERE USER_ = @Id\n\nDELETE dbo.USERINFO\nWHERE [NETWORKALIAS] = @Email AND [ID] != 'ADMIN'"
  },
  {
    "path": "d365fo.tools/internal/sql/rename-computer.sql",
    "content": "﻿BEGIN TRY\n\tEXEC sp_dropserver @@SERVERNAME;\nEND TRY\nBEGIN CATCH\n\tPRINT 'Old SQL server name could not be dropped!'\nEND CATCH\n\nEXEC sp_addserver [@NewComputerName], local;\n"
  },
  {
    "path": "d365fo.tools/internal/sql/set-aadusersecurityind365fo.sql",
    "content": "﻿/*Variable input @Id */\nDROP TABLE IF EXISTS #TempSecurityUserRole\nDROP TABLE IF EXISTS #TempRecIds\n\nBEGIN TRANSACTION\n\nSET NOCOUNT ON;\n\nDECLARE @TableId AS int\n        ,@RecId AS bigint\n\t\t,@AdminUserId as NVARCHAR(40) = 'Admin'\n\t\t,@InitialPartionKey as nvarchar(10) = 'initial'\n\n\nSELECT \n\t@Id as USER_,\n\tSECURITYUSERROLE.SECURITYROLE,\n\tSECURITYUSERROLE.ASSIGNMENTSTATUS,\n\tSECURITYUSERROLE.ASSIGNMENTMODE,\n\tSECURITYUSERROLE.VALIDFROM,\n\tSECURITYUSERROLE.VALIDFROMTZID,\n\tSECURITYUSERROLE.VALIDTO,\n\tSECURITYUSERROLE.VALIDTOTZID,\n\tSECURITYUSERROLE.PARTITION\nINTO #TempSecurityUserRole\nFROM SECURITYUSERROLE\nJOIN [PARTITIONS] ON [PARTITIONS].Recid = SECURITYUSERROLE.PARTITION\nWHERE [User_] = @AdminUserId\n\tAND PARTITIONKEY = @InitialPartionKey\n\n\nINSERT INTO SECURITYUSERROLE (\n\tUSER_,\n\tSECURITYROLE,\n\tASSIGNMENTSTATUS,\n\tASSIGNMENTMODE,\n\tVALIDFROM,\n\tVALIDFROMTZID,\n\tVALIDTO,\n\tVALIDTOTZID,\n\tPARTITION\n)\nSELECT * FROM #TempSecurityUserRole\n\nDROP TABLE #TempSecurityUserRole\n/* DROP TABLE #TempRecIds \n*/\n\ncommit TRANSACTION\n\nDeclare @AdminSecurityRoleCount as int\n\nSELECT @AdminSecurityRoleCount = count(1) \nFROM SECURITYUSERROLE \nJOIN [PARTITIONS] ON [PARTITIONS].Recid = SECURITYUSERROLE.PARTITION\nWHERE [User_] = @AdminUserId\nAND PARTITIONKEY = @InitialPartionKey\n\nDeclare @ImportSecurityRoleCount as int\n\nSELECT @ImportSecurityRoleCount = count(1) \nFROM SECURITYUSERROLE \nJOIN [PARTITIONS] ON [PARTITIONS].Recid = SECURITYUSERROLE.PARTITION\nWHERE [User_] = @Id\nAND PARTITIONKEY =  @InitialPartionKey\n\nSET Nocount OFF;\n\nselect @AdminSecurityRoleCount - @ImportSecurityRoleCount"
  },
  {
    "path": "d365fo.tools/internal/sql/set-bacpacvaluesazure.sql",
    "content": "﻿CREATE USER axdeployuser FROM LOGIN axdeployuser\nEXEC sp_addrolemember 'db_owner', 'axdeployuser'\n\nCREATE USER axdeployextuser WITH PASSWORD = '@axdeployextuser'\nIF EXISTS (select * from sys.database_principals where type = 'R' and name = 'DeployExtensibilityRole')\nBEGIN\n    EXEC sp_addrolemember 'DeployExtensibilityRole', 'axdeployextuser'\nEND\n\nIF EXISTS (select * from sys.database_principals where type = 'R' and name = 'driuser')\nBEGIN\n    CREATE USER axdbreadonlyuser WITH PASSWORD = '@axdbreadonlyuser'\n    EXEC sp_addrolemember 'driuser', 'axdbreadonlyuser'\nEND\n\nCREATE USER axdbadmin WITH PASSWORD = '@axdbadmin'\nEXEC sp_addrolemember 'db_owner', 'axdbadmin'\n\nCREATE USER axruntimeuser WITH PASSWORD = '@axruntimeuser'\nEXEC sp_addrolemember 'db_datareader', 'axruntimeuser'\nEXEC sp_addrolemember 'db_datawriter', 'axruntimeuser'\n\nCREATE USER axmrruntimeuser WITH PASSWORD = '@axmrruntimeuser'\nEXEC sp_addrolemember 'ReportingIntegrationUser', 'axmrruntimeuser'\nEXEC sp_addrolemember 'db_datareader', 'axmrruntimeuser'\nEXEC sp_addrolemember 'db_datawriter', 'axmrruntimeuser'\n\nCREATE USER axretailruntimeuser WITH PASSWORD = '@axretailruntimeuser'\nEXEC sp_addrolemember 'UsersRole', 'axretailruntimeuser'\nEXEC sp_addrolemember 'ReportUsersRole', 'axretailruntimeuser'\n\nCREATE USER axretaildatasyncuser WITH PASSWORD = '@axretaildatasyncuser'\nEXEC sp_addrolemember 'DataSyncUsersRole', 'axretaildatasyncuser'\n\nALTER DATABASE SCOPED CONFIGURATION  SET MAXDOP=2\nALTER DATABASE SCOPED CONFIGURATION  SET LEGACY_CARDINALITY_ESTIMATION=ON\nALTER DATABASE SCOPED CONFIGURATION  SET PARAMETER_SNIFFING= ON\nALTER DATABASE SCOPED CONFIGURATION  SET QUERY_OPTIMIZER_HOTFIXES=OFF\n\n\nDeclare @DB as nvarchaR(100) = db_Name(db_id())\n\n\nDeclare @Command as nvarchar(2000) =  'ALTER DATABASE [' + @DB  + ']  SET COMPATIBILITY_LEVEL = 130;ALTER DATABASE [' + @DB  + '] SET QUERY_STORE = ON;'\n\nexec (@Command)\n\nupdate [dbo].[SYSSERVICECONFIGURATIONSETTING]\nset value = @Tenantid\nwhere name = 'TENANTID'\n\nupdate dbo.POWERBICONFIG\nset TENANTID = @Tenantid\n\nupdate dbo.PROVISIONINGMESSAGETABLE\nset TENANTID = @Tenantid,\nPLANID = @PlanId,\nPLANCAPABILITY = @PlanCapability\n\n\n-- Begin Refresh Retail FullText Catalogs\nDECLARE @RFTXNAME NVARCHAR(MAX);\nDECLARE @RFTXSQL NVARCHAR(MAX);\nDECLARE retail_ftx CURSOR FOR\nSELECT OBJECT_SCHEMA_NAME(object_id) + '.' + OBJECT_NAME(object_id) fullname FROM SYS.FULLTEXT_INDEXES\n    WHERE FULLTEXT_CATALOG_ID = (SELECT TOP 1 FULLTEXT_CATALOG_ID FROM SYS.FULLTEXT_CATALOGS WHERE NAME = 'COMMERCEFULLTEXTCATALOG');\nOPEN retail_ftx;\nFETCH NEXT FROM retail_ftx INTO @RFTXNAME;\n\nBEGIN TRY\n    WHILE @@FETCH_STATUS = 0  \n    BEGIN  \n        PRINT 'Refreshing Full Text Index ' + @RFTXNAME;\n        EXEC SP_FULLTEXT_TABLE @RFTXNAME, 'activate';\n        SET @RFTXSQL = 'ALTER FULLTEXT INDEX ON ' + @RFTXNAME + ' START FULL POPULATION';\n        EXEC SP_EXECUTESQL @RFTXSQL;\n        FETCH NEXT FROM retail_ftx INTO @RFTXNAME;\n    END\nEND TRY\nBEGIN CATCH\n\nPRINT error_message()\nEND CATCH\n\nCLOSE retail_ftx;  \nDEALLOCATE retail_ftx; \n-- End Refresh Retail FullText Catalogs"
  },
  {
    "path": "d365fo.tools/internal/sql/set-bacpacvaluessql.sql",
    "content": "﻿--Author: Rasmus Andersen (@ITRasmus)\n--Author: Tommy Skaue (@skaue)\n--Author: Mötz Jensen (@Splaxi)\n\nDROP USER IF EXISTS [axretailruntimeuser]\nDROP USER IF EXISTS [axretaildatasyncuser]\nDROP USER IF EXISTS [axmrruntimeuser]\nDROP USER IF EXISTS [axdeployuser]\nDROP USER IF EXISTS [axdbadmin]\nDROP USER IF EXISTS [axdeployextuser]\nDROP USER IF EXISTS [NT AUTHORITY\\NETWORK SERVICE]\n\nIF EXISTS (SELECT * FROM sys.syslogins WHERE NAME = 'axdeployuser')\nBEGIN\n\tCREATE USER axdeployuser FROM LOGIN axdeployuser\n\tEXEC sp_addrolemember 'db_owner', 'axdeployuser'\nEND\n\nIF EXISTS (SELECT * FROM sys.syslogins WHERE NAME = 'axdbadmin')\nBEGIN\n\tALTER AUTHORIZATION ON database::[@DATABASENAME] TO sa\n\n\tCREATE USER axdbadmin FROM LOGIN axdbadmin\n\tEXEC sp_addrolemember 'db_owner', 'axdbadmin'\nEND\n\nIF EXISTS (SELECT * FROM sys.syslogins WHERE NAME = 'axmrruntimeuser')\nBEGIN\n\tCREATE USER axmrruntimeuser FROM LOGIN axmrruntimeuser\n\tEXEC sp_addrolemember 'db_datareader', 'axmrruntimeuser'\n\tEXEC sp_addrolemember 'db_datawriter', 'axmrruntimeuser'\nEND\n\nIF EXISTS (SELECT * FROM sys.syslogins WHERE NAME = 'axretaildatasyncuser')\nBEGIN\n\tCREATE USER axretaildatasyncuser FROM LOGIN axretaildatasyncuser\n\tIF (DATABASE_PRINCIPAL_ID('DataSyncUsersRole') IS NOT NULL)\n\tBEGIN\n\t\tEXEC sp_addrolemember 'DataSyncUsersRole', 'axretaildatasyncuser'\n\tEND\nEND\n\nIF EXISTS (SELECT * FROM sys.syslogins WHERE NAME = 'axretailruntimeuser')\nBEGIN\n\tCREATE USER axretailruntimeuser FROM LOGIN axretailruntimeuser\n\tIF (DATABASE_PRINCIPAL_ID('UsersRole') IS NOT NULL)\n\tBEGIN\n\t\tEXEC sp_addrolemember 'UsersRole', 'axretailruntimeuser'\n\n\tEND\n\t\n\tIF (DATABASE_PRINCIPAL_ID('ReportUsersRole') IS NOT NULL)\n\tBEGIN\n\t\tEXEC sp_addrolemember 'ReportUsersRole', 'axretailruntimeuser'\n\tEND\nEND\n\nIF EXISTS (SELECT * FROM sys.syslogins WHERE NAME = 'axdeployextuser')\nBEGIN\n\tCREATE USER axdeployextuser FROM LOGIN axdeployextuser\n\tIF (DATABASE_PRINCIPAL_ID('DeployExtensibilityRole') IS NOT NULL)\n\tBEGIN\n\t\tEXEC sp_addrolemember 'DeployExtensibilityRole', 'axdeployextuser'\n\tEND\nEND\n\nCREATE USER [NT AUTHORITY\\NETWORK SERVICE] FROM LOGIN [NT AUTHORITY\\NETWORK SERVICE]\nEXEC sp_addrolemember 'db_owner', 'NT AUTHORITY\\NETWORK SERVICE'\n\nUPDATE T1\nSET T1.storageproviderid = 0\n    , T1.accessinformation = ''\n    , T1.modifiedby = 'Admin'\n    , T1.modifieddatetime = getdate()\nFROM docuvalue T1\nWHERE T1.storageproviderid = 1 --Azure storage\n\n\nIF((SELECT 1\nFROM SYS.CHANGE_TRACKING_DATABASES\nWHERE DATABASE_ID = DB_ID('@DATABASENAME')) IS NULL)\nBEGIN\n\tALTER DATABASE [@DATABASENAME] SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 6 DAYS, AUTO_CLEANUP = ON)\nEND\n\n;--GO\nDROP PROCEDURE IF EXISTS SP_ConfigureTablesForChangeTracking\nDROP PROCEDURE IF EXISTS SP_ConfigureTablesForChangeTracking_V2\n;--GO\n-- Begin Refresh Retail FullText Catalogs\nDECLARE @RFTXNAME NVARCHAR(MAX);\nDECLARE @RFTXSQL NVARCHAR(MAX);\nDECLARE retail_ftx CURSOR FOR\nSELECT OBJECT_SCHEMA_NAME(object_id) + '.' + OBJECT_NAME(object_id) fullname\nFROM SYS.FULLTEXT_INDEXES\nWHERE FULLTEXT_CATALOG_ID = (SELECT TOP 1\n\tFULLTEXT_CATALOG_ID\nFROM SYS.FULLTEXT_CATALOGS\nWHERE NAME = 'COMMERCEFULLTEXTCATALOG');\nOPEN retail_ftx;\nFETCH NEXT FROM retail_ftx INTO @RFTXNAME;\n\nBEGIN TRY\n\tWHILE @@FETCH_STATUS = 0\n\tBEGIN\n\t\tPRINT 'Refreshing Full Text Index ' + @RFTXNAME;\n\t\tEXEC SP_FULLTEXT_TABLE @RFTXNAME, 'activate';\n\t\tSET @RFTXSQL = 'ALTER FULLTEXT INDEX ON ' + @RFTXNAME + ' START FULL POPULATION';\n\t\tEXEC SP_EXECUTESQL @RFTXSQL;\n\t\tFETCH NEXT FROM retail_ftx INTO @RFTXNAME;\n\tEND\nEND TRY\nBEGIN CATCH\n\tPRINT error_message()\nEND CATCH\n\nCLOSE retail_ftx;\nDEALLOCATE retail_ftx;\n-- End Refresh Retail FullText Catalogs\n\n--Next, set system parameters ready for being a SQL Server Database.\nUPDATE sysglobalconfiguration\nSET    value = 'SQLSERVER'\nWHERE  NAME = 'BACKENDDB'\n\nUPDATE sysglobalconfiguration\nSET    value = 0\nWHERE  NAME = 'TEMPTABLEINAXDB'"
  },
  {
    "path": "d365fo.tools/internal/sql/set-sysadmin.sql",
    "content": "﻿USE [master]\nCREATE LOGIN [@USER] FROM WINDOWS WITH DEFAULT_DATABASE=[master]\nALTER SERVER ROLE [sysadmin] ADD MEMBER [@USER]\n\n"
  },
  {
    "path": "d365fo.tools/internal/sql/switch-database-tier1.sql",
    "content": "/*\n    Author: Oleksandr Nikolaiev (@onikolaiev)\n*/\n\nDeclare @Command as nvarchar(2000)\n\nset @Command =' ALTER DATABASE ['+ @DestinationName + '] SET AUTO_UPDATE_STATISTICS_ASYNC OFF;\n                ALTER DATABASE ['+ @DestinationName + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;\n                ALTER DATABASE ['+ @DestinationName + '] MODIFY NAME = [' + @ToBeName + '];\n                ALTER DATABASE ['+ @SourceName + '] SET AUTO_UPDATE_STATISTICS_ASYNC OFF;\n                ALTER DATABASE ['+ @SourceName + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;\n                ALTER DATABASE ['+ @SourceName +'] MODIFY NAME = ['+ @DestinationName +'];\n                ALTER DATABASE ['+ @DestinationName + '] SET MULTI_USER;\n                ALTER DATABASE ['+ @DestinationName + '] SET AUTO_UPDATE_STATISTICS_ASYNC ON;\n                ALTER DATABASE ['+ @ToBeName + '] SET MULTI_USER;\n                ALTER DATABASE ['+ @ToBeName + '] SET AUTO_UPDATE_STATISTICS_ASYNC ON;\n                ALTER DATABASE ['+ @DestinationName + '] SET AUTO_CLOSE OFF WITH NO_WAIT\n                '\n\nexec (@Command)\n"
  },
  {
    "path": "d365fo.tools/internal/sql/switch-database-tier2.sql",
    "content": "﻿\nDeclare @Command as nvarchar(2000)\n\n\nset @Command =' ALTER DATABASE ['+ @DestinationName + '] MODIFY NAME = [' + @ToBeName + '];\n                ALTER DATABASE ['+ @SourceName +'] MODIFY NAME = ['+ @DestinationName +'];\n                '\n\nexec (@Command)"
  },
  {
    "path": "d365fo.tools/internal/sql/test-aaduseridind365fo.sql",
    "content": "﻿/* Variable input @Id */\n\nselect count(1) from USERINFO\nwhere [ID] = @Id"
  },
  {
    "path": "d365fo.tools/internal/sql/test-aaduserind365fo.sql",
    "content": "﻿/* Variable input @Email */\n\nselect count(1) from USERINFO\nwhere NETWORKALIAS = @Email"
  },
  {
    "path": "d365fo.tools/internal/sql/update-user.sql",
    "content": "﻿update userinfo\nset [sid] = @sid,\nNETWORKDOMAIN = @networkDomain,\nIDENTITYPROVIDER = @identityProvider\n, COMPANY = CASE WHEN @Company IS NULL THEN COMPANY ELSE @Company END\nwhere [ID] = @id\nAND [Id] <> 'admin'"
  },
  {
    "path": "d365fo.tools/internal/tepp/assignment.ps1",
    "content": "﻿<#\n# Example:\nRegister-PSFTeppArgumentCompleter -Command Get-Alcohol -Parameter Type -Name d365fo.tools.alcohol\n#>\n\n#File Options\nRegister-PSFTeppArgumentCompleter -Command Invoke-D365LcsUpload -Parameter FileType -Name d365fo.tools.lcs.options\nRegister-PSFTeppArgumentCompleter -Command Get-D365LcsAssetFile -Parameter FileType -Name d365fo.tools.lcs.options\n\n#LCS API URLS\nRegister-PSFTeppArgumentCompleter -Command Get-D365LcsApiToken -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls\nRegister-PSFTeppArgumentCompleter -Command Get-D365LcsAssetFile -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls\nRegister-PSFTeppArgumentCompleter -Command Get-D365LcsAssetValidationStatus -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls\nRegister-PSFTeppArgumentCompleter -Command Get-D365LcsDatabaseBackups -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls\nRegister-PSFTeppArgumentCompleter -Command Get-D365LcsDatabaseOperationStatus -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls\nRegister-PSFTeppArgumentCompleter -Command Get-D365LcsDeploymentStatus -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls\nRegister-PSFTeppArgumentCompleter -Command Get-D365LcsEnvironmentHistory -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls\nRegister-PSFTeppArgumentCompleter -Command Get-D365LcsEnvironmentMetadata -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls\nRegister-PSFTeppArgumentCompleter -Command Get-D365LcsSharedAssetFile -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls\n\nRegister-PSFTeppArgumentCompleter -Command Invoke-D365LcsDatabaseExport -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls\nRegister-PSFTeppArgumentCompleter -Command Invoke-D365LcsDatabaseRefresh -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls\nRegister-PSFTeppArgumentCompleter -Command Invoke-D365LcsDeployment -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls\nRegister-PSFTeppArgumentCompleter -Command Invoke-D365LcsEnvironmentStart -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls\nRegister-PSFTeppArgumentCompleter -Command Invoke-D365LcsEnvironmentStop -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls\nRegister-PSFTeppArgumentCompleter -Command Invoke-D365LcsUpload -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls\n\nRegister-PSFTeppArgumentCompleter -Command Set-D365LcsApiConfig -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls\n\n#TimeZones\nRegister-PSFTeppArgumentCompleter -Command Send-D365BroadcastMessage -Parameter TimeZone -Name d365fo.tools.timezones\nRegister-PSFTeppArgumentCompleter -Command Add-D365BroadcastMessageConfig -Parameter TimeZone -Name d365fo.tools.timezones\n\n#Event Trace\nRegister-PSFTeppArgumentCompleter -Command Start-D365EventTrace -Parameter ProviderName -Name d365fo.tools.event.trace.providers\nRegister-PSFTeppArgumentCompleter -Command Start-D365EventTrace -Parameter OutputFormat -Name d365fo.tools.event.trace.format.options\n"
  },
  {
    "path": "d365fo.tools/internal/tepp/eventtrace.tepp.ps1",
    "content": "﻿$scriptBlock = { (Get-NetEventProvider -ShowInstalled | Where-Object name -like \"Microsoft-Dynamics*\" | Sort-Object Name).Name }\n\nRegister-PSFTeppScriptblock -Name \"d365fo.tools.event.trace.providers\" -ScriptBlock $scriptBlock -Mode Simple\n\nRegister-PSFTeppScriptblock -Name \"d365fo.tools.event.trace.format.options\" -ScriptBlock { 'bin', 'bincirc', 'csv', 'sql', 'tsv' }\n\n"
  },
  {
    "path": "d365fo.tools/internal/tepp/example.tepp.ps1",
    "content": "﻿<#\n# Example:\nRegister-PSFTeppScriptblock -Name \"d365fo.tools.alcohol\" -ScriptBlock { 'Beer','Mead','Whiskey','Wine','Vodka','Rum (3y)', 'Rum (5y)', 'Rum (7y)' }\n#>"
  },
  {
    "path": "d365fo.tools/internal/tepp/lcs.tepp.ps1",
    "content": "﻿<#\n\"options\": {\n    \"1\": \"Model\",\n    \"4\": \"Process Data Package\",\n    \"10\": \"Software Deployable Package\",\n    \"12\": \"GER Configuration\",\n    \"15\": \"Data Package\",\n    \"19\": \"PowerBI Report Model\"\n}\n#>\nRegister-PSFTeppScriptblock -Name \"d365fo.tools.lcs.options\" -ScriptBlock { [LcsAssetFileType]::Model, [LcsAssetFileType]::ProcessDataPackage, [LcsAssetFileType]::SoftwareDeployablePackage, [LcsAssetFileType]::GERConfiguration, [LcsAssetFileType]::DataPackage, [LcsAssetFileType]::PowerBIReportModel, [LcsAssetFileType]::ECommercePackage, [LcsAssetFileType]::NuGetPackage, [LcsAssetFileType]::RetailSelfServicePackage, [LcsAssetFileType]::CommerceCloudScaleUnitExtension }\n\n\n<#\n[ValidateSet(\"https://lcsapi.lcs.dynamics.com\", \"https://lcsapi.eu.lcs.dynamics.com\")]\n#>\nRegister-PSFTeppScriptblock -Name \"d365fo.tools.lcs.api.urls\" -ScriptBlock { 'https://lcsapi.lcs.dynamics.com', 'https://lcsapi.eu.lcs.dynamics.com', 'https://lcsapi.fr.lcs.dynamics.com', 'https://lcsapi.sa.lcs.dynamics.com', 'https://lcsapi.uae.lcs.dynamics.com', 'https://lcsapi.ch.lcs.dynamics.com', 'https://lcsapi.no.lcs.dynamics.com', 'https://lcsapi.lcs.dynamics.cn', 'https://lcsapi.gov.lcs.microsoftdynamics.us' }\n\n"
  },
  {
    "path": "d365fo.tools/internal/tepp/readme.md",
    "content": "﻿# Tab Expansion\n\n## Description\n\nModern Tab Expansion was opened to users with the module `Tab Expansion Plus Plus` (TEPP).\n\nIt allows you to define, what options a user is offered when tabbing through input options. This can save a lot of time for the user and is considered a key element in user experience.\n\nThe `PSFramework` offers a simplified way of offering just this, as the two example files show.\n\n## Concept\n\nCustom tab completion is defined in two steps:\n\n - Define a scriptblock that is run when the user hits `TAB` and provides the strings that are his options.\n - Assign that scriptblock to the parameter of a command. You can assign the same scriptblock multiple times.\n\n## Structure\n\nImport order matters. In order to make things work with the default scaffold, follow those rules:\n\n - All scriptfiles _defining_ completion scriptblocks like this: `*.tepp.ps1`\n - Put all your completion assignments in `assignment.ps1`"
  },
  {
    "path": "d365fo.tools/internal/tepp/send-d365message.tepp.ps1",
    "content": "﻿<#\n# Example:\nRegister-PSFTeppScriptblock -Name \"d365fo.tools.alcohol\" -ScriptBlock { 'Beer','Mead','Whiskey','Wine','Vodka','Rum (3y)', 'Rum (5y)', 'Rum (7y)' }\n#>\n\n# Register-PSFTeppScriptblock -Name \"d365fo.tools.timezones\" -ScriptBlock { [System.TimeZoneInfo]::GetSystemTimeZones().Id }\n\n\nRegister-PSFTeppScriptblock -Name \"d365fo.tools.timezones\" -ScriptBlock {\n    param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)\n\t\n    [System.TimeZoneInfo]::GetSystemTimeZones() | Where-Object {$PSItem.DisplayName -match $wordToComplete} | ForEach-Object {\n        $CompletionText = '\"{0} - [{1}]\"' -f $PSItem.DisplayName, $PSItem.StandardName\n\t\n        New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList @($CompletionText)\n    }\n}"
  },
  {
    "path": "d365fo.tools/readme.md",
    "content": "﻿# PSFModule guidance\n\nThis is a finished module layout optimized for implementing the PSFramework.\n\nIf you don't care to deal with the details, this is what you need to do to get started seeing results:\n\n - Add the functions you want to publish to `/functions/`\n - Update the `FunctionsToExport` node in the module manifest (d365fo.tools.psd1). All functions you want to publish should be in a list.\n - Add internal helper functions the user should not see to `/internal/functions/`\n \n ## Path Warning\n \n > If you want your module to be compatible with Linux and MacOS, keep in mind that those OS are case sensitive for paths and files.\n \n `Import-ModuleFile` is preconfigured to resolve the path of the files specified, so it will reliably convert weird path notations the system can't handle.\n Content imported through that command thus need not mind the path separator.\n If you want to make sure your code too will survive OS-specific path notations, get used to using `Resolve-path` or the more powerful `Resolve-PSFPath`."
  },
  {
    "path": "d365fo.tools/tests/examples/Get-DeepClone.Tests.ps1",
    "content": "﻿$commandName = \"Get-DeepClone\"\n$exampleRaw = \"PS C:\\> Get-DeepClone -InputObject `$HashTable\"\n\n$HashTable = @{}\n\n$example = $exampleRaw -replace \"`n.*\" -replace \"PS C:\\\\>\" \n\nDescribe \"Specific example testing for $commandName\" {\n\n    It \"Example - $example\" {\n        # mock the tested command so we don't actually do anything\n        # because it can be unsafe and we don't have the environment setup\n        # (so the only thing we are testing is that the code is semantically\n        # correct and provides all the needed params)\n        Mock $commandName { \n            # I am returning true here,\n            # but some of the examples drill down to the returned object\n            # so in strict mode we would fail\n            $true \n        }\n\n        # here simply invoke the example\n        $result = Invoke-Expression $example\n        # and check that we got result from the mock\n        $result | Should -BeTrue\n    }\n}"
  },
  {
    "path": "d365fo.tools/tests/examples/Import-D365Bacpac.Tests.ps1",
    "content": "﻿$commandName = \"Import-D365Bacpac\"\n################################### New Example test ###################################\n\n$exampleRaw = \"Import-D365Bacpac -ImportModeTier1 -BacpacFile `\"C:\\temp\\uat.bacpac`\" -NewDatabaseName `\"ImportedDatabase`\"\"\n#Remember to escape any variables names in the line above.\n#Remember to you need to output $true to the pester test, otherwise is fails.\n#; `$var -eq `$true\n\n#Here you declare any variable(s) you need to complete the test.\n\n$example = $exampleRaw -replace \"`n.*\" -replace \"PS C:\\\\>\"\n\nDescribe \"Specific example testing for $commandName\" {\n\nIt \"Example - $example\" {\n# mock the tested command so we don't actually do anything\n# because it can be unsafe and we don't have the environment setup\n# (so the only thing we are testing is that the code is semantically\n# correct and provides all the needed params)\nMock $commandName {\n# I am returning true here,\n# but some of the examples drill down to the returned object\n# so in strict mode we would fail\n$true\n}\n# here simply invoke the example\n$result = Invoke-Expression $example\n# and check that we got result from the mock\n$result | Should -BeTrue\n}\n}\n################################### New Example test ###################################\n\n$exampleRaw = \"Import-D365Bacpac -ImportModeTier2 -SqlUser `\"sqladmin`\" -SqlPwd `\"XyzXyz`\" -BacpacFile `\"C:\\temp\\uat.bacpac`\" -AxDeployExtUserPwd `\"XxXx`\" -AxDbAdminPwd `\"XxXx`\" -AxRuntimeUserPwd `\"XxXx`\" -AxMrRuntimeUserPwd `\"XxXx`\" -AxRetailRuntimeUserPwd `\"XxXx`\" -AxRetailDataSyncUserPwd `\"XxXx`\" -AxDbReadonlyUserPwd `\"XxXx`\" -NewDatabaseName `\"ImportedDatabase`\"\"\n#Remember to escape any variables names in the line above.\n#Remember to you need to output $true to the pester test, otherwise is fails.\n#; `$var -eq `$true\n\n#Here you declare any variable(s) you need to complete the test.\n\n$example = $exampleRaw -replace \"`n.*\" -replace \"PS C:\\\\>\"\n\nDescribe \"Specific example testing for $commandName\" {\n\nIt \"Example - $example\" {\n# mock the tested command so we don't actually do anything\n# because it can be unsafe and we don't have the environment setup\n# (so the only thing we are testing is that the code is semantically\n# correct and provides all the needed params)\nMock $commandName {\n# I am returning true here,\n# but some of the examples drill down to the returned object\n# so in strict mode we would fail\n$true\n}\n# here simply invoke the example\n$result = Invoke-Expression $example\n# and check that we got result from the mock\n$result | Should -BeTrue\n}\n}\n################################### New Example test ###################################\n\n$exampleRaw = \"Import-D365Bacpac -ImportModeTier1 -BacpacFile `\"C:\\temp\\uat.bacpac`\" -NewDatabaseName `\"ImportedDatabase`\" -DiagnosticFile `\"C:\\temp\\ImportLog.txt`\"\"\n#Remember to escape any variables names in the line above.\n#Remember to you need to output $true to the pester test, otherwise is fails.\n#; `$var -eq `$true\n\n#Here you declare any variable(s) you need to complete the test.\n\n$example = $exampleRaw -replace \"`n.*\" -replace \"PS C:\\\\>\"\n\nDescribe \"Specific example testing for $commandName\" {\n\nIt \"Example - $example\" {\n# mock the tested command so we don't actually do anything\n# because it can be unsafe and we don't have the environment setup\n# (so the only thing we are testing is that the code is semantically\n# correct and provides all the needed params)\nMock $commandName {\n# I am returning true here,\n# but some of the examples drill down to the returned object\n# so in strict mode we would fail\n$true\n}\n# here simply invoke the example\n$result = Invoke-Expression $example\n# and check that we got result from the mock\n$result | Should -BeTrue\n}\n}\n################################### Entire help loaded ###################################\n\n<#\n\n\nNAME\n    Import-D365Bacpac\n    \nSYNOPSIS\n    Import a bacpac file\n    \n    \nSYNTAX\n    Import-D365Bacpac [-ImportModeTier1] [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>] \n    [[-SqlPwd] <String>] [-BacpacFile] <String> [-NewDatabaseName] <String> [[-CustomSqlFile] <String>] [-DiagnosticFil\n    e <String>] [-ImportOnly] [-EnableException] [<CommonParameters>]\n    \n    Import-D365Bacpac [-ImportModeTier2] [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [-SqlUser] <String> [-\n    SqlPwd] <String> [-BacpacFile] <String> [-NewDatabaseName] <String> [[-AxDeployExtUserPwd] <String>] [[-AxDbAdminPw\n    d] <String>] [[-AxRuntimeUserPwd] <String>] [[-AxMrRuntimeUserPwd] <String>] [[-AxRetailRuntimeUserPwd] <String>] [\n    [-AxRetailDataSyncUserPwd] <String>] [[-AxDbReadonlyUserPwd] <String>] [[-CustomSqlFile] <String>] [-DiagnosticFile\n     <String>] -ImportOnly [-EnableException] [<CommonParameters>]\n    \n    Import-D365Bacpac [-ImportModeTier2] [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [-SqlUser] <String> [-\n    SqlPwd] <String> [-BacpacFile] <String> [-NewDatabaseName] <String> [-AxDeployExtUserPwd] <String> [-AxDbAdminPwd] \n    <String> [-AxRuntimeUserPwd] <String> [-AxMrRuntimeUserPwd] <String> [-AxRetailRuntimeUserPwd] <String> [-AxRetailD\n    ataSyncUserPwd] <String> [-AxDbReadonlyUserPwd] <String> [[-CustomSqlFile] <String>] [-DiagnosticFile <String>] [-E\n    nableException] [<CommonParameters>]\n    \n    \nDESCRIPTION\n    Import a bacpac file to either a Tier1 or Tier2 environment\n    \n\nPARAMETERS\n    -ImportModeTier1 [<SwitchParameter>]\n        Switch to instruct the cmdlet that it will import into a Tier1 environment\n        \n        The cmdlet will expect to work against a SQL Server instance\n        \n        Required?                    true\n        Position?                    1\n        Default value                False\n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -ImportModeTier2 [<SwitchParameter>]\n        Switch to instruct the cmdlet that it will import into a Tier2 environment\n        \n        The cmdlet will expect to work against an Azure DB instance\n        \n        Required?                    true\n        Position?                    1\n        Default value                False\n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -DatabaseServer <String>\n        The name of the database server\n        \n        If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n        \n        If Azure use the full address to the database server, e.g. server.database.windows.net\n        \n        Required?                    false\n        Position?                    2\n        Default value                $Script:DatabaseServer\n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -DatabaseName <String>\n        The name of the database\n        \n        Required?                    false\n        Position?                    3\n        Default value                $Script:DatabaseName\n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -SqlUser <String>\n        The login name for the SQL Server instance\n        \n        Required?                    false\n        Position?                    4\n        Default value                $Script:DatabaseUserName\n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -SqlPwd <String>\n        The password for the SQL Server user\n        \n        Required?                    false\n        Position?                    5\n        Default value                $Script:DatabaseUserPassword\n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -BacpacFile <String>\n        Path to the bacpac file you want to import into the database server\n        \n        Required?                    true\n        Position?                    6\n        Default value                \n        Accept pipeline input?       true (ByPropertyName)\n        Accept wildcard characters?  false\n        \n    -NewDatabaseName <String>\n        Name of the new database that will be created while importing the bacpac file\n        \n        This will create a new database on the database server and import the content of the bacpac into\n        \n        Required?                    true\n        Position?                    7\n        Default value                \n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -AxDeployExtUserPwd <String>\n        Password that is obtained from LCS\n        \n        Required?                    false\n        Position?                    8\n        Default value                \n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -AxDbAdminPwd <String>\n        Password that is obtained from LCS\n        \n        Required?                    false\n        Position?                    9\n        Default value                \n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -AxRuntimeUserPwd <String>\n        Password that is obtained from LCS\n        \n        Required?                    false\n        Position?                    10\n        Default value                \n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -AxMrRuntimeUserPwd <String>\n        Password that is obtained from LCS\n        \n        Required?                    false\n        Position?                    11\n        Default value                \n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -AxRetailRuntimeUserPwd <String>\n        Password that is obtained from LCS\n        \n        Required?                    false\n        Position?                    12\n        Default value                \n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -AxRetailDataSyncUserPwd <String>\n        Password that is obtained from LCS\n        \n        Required?                    false\n        Position?                    13\n        Default value                \n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -AxDbReadonlyUserPwd <String>\n        Password that is obtained from LCS\n        \n        Required?                    false\n        Position?                    14\n        Default value                \n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -CustomSqlFile <String>\n        Path to the sql script file that you want the cmdlet to execute against your data after it has been imported\n        \n        Required?                    false\n        Position?                    15\n        Default value                \n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -DiagnosticFile <String>\n        Path to where you want the import to output a diagnostics file to assist you in troubleshooting the import\n        \n        Required?                    false\n        Position?                    named\n        Default value                \n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -ImportOnly [<SwitchParameter>]\n        Switch to instruct the cmdlet to only import the bacpac into the new database\n        \n        The cmdlet will create a new database and import the content of the bacpac file into this\n        \n        Nothing else will be executed\n        \n        Required?                    false\n        Position?                    named\n        Default value                False\n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    -EnableException [<SwitchParameter>]\n        This parameters disables user-friendly warnings and enables the throwing of exceptions\n        This is less user friendly, but allows catching exceptions in calling scripts\n        \n        Required?                    false\n        Position?                    named\n        Default value                False\n        Accept pipeline input?       false\n        Accept wildcard characters?  false\n        \n    <CommonParameters>\n        This cmdlet supports the common parameters: Verbose, Debug,\n        ErrorAction, ErrorVariable, WarningAction, WarningVariable,\n        OutBuffer, PipelineVariable, and OutVariable. For more information, see \n        about_CommonParameters (https:/go.microsoft.com/fwlink/?LinkID=113216). \n    \nINPUTS\n    \nOUTPUTS\n    \nNOTES\n    \n    \n        Tags: Database, Bacpac, Tier1, Tier2, Golden Config, Config, Configuration\n        \n        Author: Rasmus Andersen (@ITRasmus)\n        Author: Mötz Jensen (@Splaxi)\n    \n    -------------------------- EXAMPLE 1 --------------------------\n    \n    PS C:\\>Import-D365Bacpac -ImportModeTier1 -BacpacFile \"C:\\temp\\uat.bacpac\" -NewDatabaseName \"ImportedDatabase\"\n    \n    PS C:\\> Switch-D365ActiveDatabase -NewDatabaseName \"ImportedDatabase\"\n    \n    This will instruct the cmdlet that the import will be working against a SQL Server instance.\n    It will import the \"C:\\temp\\uat.bacpac\" file into a new database named \"ImportedDatabase\".\n    The next thing to do is to switch the active database out with the new one you just imported.\n    \"ImportedDatabase\" will be switched in as the active database, while the old one will be named \"AXDB_original\".\n    \n    \n    \n    \n    -------------------------- EXAMPLE 2 --------------------------\n    \n    PS C:\\>Import-D365Bacpac -ImportModeTier2 -SqlUser \"sqladmin\" -SqlPwd \"XyzXyz\" -BacpacFile \"C:\\temp\\uat.bacpac\" -Ax\n    DeployExtUserPwd \"XxXx\" -AxDbAdminPwd \"XxXx\" -AxRuntimeUserPwd \"XxXx\" -AxMrRuntimeUserPwd \"XxXx\" -AxRetailRuntimeUs\n    erPwd \"XxXx\" -AxRetailDataSyncUserPwd \"XxXx\" -AxDbReadonlyUserPwd \"XxXx\" -NewDatabaseName \"ImportedDatabase\"\n    \n    PS C:\\> Switch-D365ActiveDatabase -NewDatabaseName \"ImportedDatabase\" -SqlUser \"sqladmin\" -SqlPwd \"XyzXyz\"\n    \n    This will instruct the cmdlet that the import will be working against an Azure DB instance.\n    It requires all relevant passwords from LCS for all the builtin user accounts used in a Tier 2 environment.\n    It will import the \"C:\\temp\\uat.bacpac\" file into a new database named \"ImportedDatabase\".\n    The next thing to do is to switch the active database out with the new one you just imported.\n    \"ImportedDatabase\" will be switched in as the active database, while the old one will be named \"AXDB_original\".\n    \n    \n    \n    \n    -------------------------- EXAMPLE 3 --------------------------\n    \n    PS C:\\>Import-D365Bacpac -ImportModeTier1 -BacpacFile \"C:\\temp\\uat.bacpac\" -NewDatabaseName \"ImportedDatabase\" -Dia\n    gnosticFile \"C:\\temp\\ImportLog.txt\"\n    \n    This will instruct the cmdlet that the import will be working against a SQL Server instance.\n    It will import the \"C:\\temp\\uat.bacpac\" file into a new database named \"ImportedDatabase\".\n    It will output a diagnostic file to \"C:\\temp\\ImportLog.txt\".\n    \n    \n    \n    \n    \nRELATED LINKS\n\n\n\n#>\n"
  },
  {
    "path": "d365fo.tools/tests/examples/Test-TrustedConnection.Tests.ps1",
    "content": "﻿$commandName = \"Test-TrustedConnection\"\n################################### New Example test ###################################\n\n$exampleRaw = \"`$UseTrustedConnection = Test-TrustedConnection `$PSBoundParameters; `$UseTrustedConnection -eq `$true\"\n#Remember to escape any variables names in the line above.\n#Remember to you need to output $true to the pester test, otherwise is fails.\n#; `$var -eq `$true\n\n#Here you declare any variable(s) you need to complete the test.\n\n$example = $exampleRaw -replace \"`n.*\" -replace \"PS C:\\\\>\"\n\nDescribe \"Specific example testing for $commandName\" {\n\n    It \"Example - $example\" {\n        # mock the tested command so we don't actually do anything\n        # because it can be unsafe and we don't have the environment setup\n        # (so the only thing we are testing is that the code is semantically\n        # correct and provides all the needed params)\n        Mock $commandName {\n            # I am returning true here,\n            # but some of the examples drill down to the returned object\n            # so in strict mode we would fail\n            $true\n        }\n        # here simply invoke the example\n        $result = Invoke-Expression $example\n        # and check that we got result from the mock\n        $result | Should -BeTrue\n    }\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Add-D365AzureStorageConfig.Tests.ps1",
    "content": "﻿Describe \"Add-D365AzureStorageConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Add-D365AzureStorageConfig).ParameterSets.Name | Should -Be 'AccessToken', 'SAS'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Add-D365AzureStorageConfig).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AccountId' {\n\t\t\t$parameter = (Get-Command Add-D365AzureStorageConfig).Parameters['AccountId']\n\t\t\t$parameter.Name | Should -Be 'AccountId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AccessToken' {\n\t\t\t$parameter = (Get-Command Add-D365AzureStorageConfig).Parameters['AccessToken']\n\t\t\t$parameter.Name | Should -Be 'AccessToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'AccessToken'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'AccessToken'\n\t\t\t$parameter.ParameterSets['AccessToken'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['AccessToken'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['AccessToken'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['AccessToken'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['AccessToken'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SAS' {\n\t\t\t$parameter = (Get-Command Add-D365AzureStorageConfig).Parameters['SAS']\n\t\t\t$parameter.Name | Should -Be 'SAS'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'SAS'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'SAS'\n\t\t\t$parameter.ParameterSets['SAS'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['SAS'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['SAS'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['SAS'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['SAS'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Container' {\n\t\t\t$parameter = (Get-Command Add-D365AzureStorageConfig).Parameters['Container']\n\t\t\t$parameter.Name | Should -Be 'Container'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Temporary' {\n\t\t\t$parameter = (Get-Command Add-D365AzureStorageConfig).Parameters['Temporary']\n\t\t\t$parameter.Name | Should -Be 'Temporary'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Add-D365AzureStorageConfig).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset AccessToken\" {\n\t\t<#\n\t\tAccessToken -Name -AccountId -AccessToken -Container\n\t\tAccessToken -Name -AccountId -AccessToken -Container -Temporary -Force\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset SAS\" {\n\t\t<#\n\t\tSAS -Name -AccountId -SAS -Container\n\t\tSAS -Name -AccountId -SAS -Container -Temporary -Force\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Add-D365BroadcastMessageConfig.Tests.ps1",
    "content": "﻿Describe \"Add-D365BroadcastMessageConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Add-D365BroadcastMessageConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Tenant' {\n\t\t\t$parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['Tenant']\n\t\t\t$parameter.Name | Should -Be 'Tenant'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter URL' {\n\t\t\t$parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['URL']\n\t\t\t$parameter.Name | Should -Be 'URL'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ClientId' {\n\t\t\t$parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['ClientId']\n\t\t\t$parameter.Name | Should -Be 'ClientId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ClientSecret' {\n\t\t\t$parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['ClientSecret']\n\t\t\t$parameter.Name | Should -Be 'ClientSecret'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter TimeZone' {\n\t\t\t$parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['TimeZone']\n\t\t\t$parameter.Name | Should -Be 'TimeZone'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EndingInMinutes' {\n\t\t\t$parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['EndingInMinutes']\n\t\t\t$parameter.Name | Should -Be 'EndingInMinutes'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OnPremise' {\n\t\t\t$parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['OnPremise']\n\t\t\t$parameter.Name | Should -Be 'OnPremise'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Temporary' {\n\t\t\t$parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['Temporary']\n\t\t\t$parameter.Name | Should -Be 'Temporary'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Name\n\t\t__AllParameterSets -Name -Tenant -URL -ClientId -ClientSecret -TimeZone -EndingInMinutes -OnPremise -Temporary -Force\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Add-D365ModuleToRemove.Tests.ps1",
    "content": "﻿Describe \"Add-D365ModuleToRemove Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Add-D365ModuleToRemove).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ModuleToRemove' {\n\t\t\t$parameter = (Get-Command Add-D365ModuleToRemove).Parameters['ModuleToRemove']\n\t\t\t$parameter.Name | Should -Be 'ModuleToRemove'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DeployablePackage' {\n\t\t\t$parameter = (Get-Command Add-D365ModuleToRemove).Parameters['DeployablePackage']\n\t\t\t$parameter.Name | Should -Be 'DeployablePackage'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Add-D365ModuleToRemove).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -ModuleToRemove -DeployablePackage\n\t\t__AllParameterSets -ModuleToRemove -DeployablePackage -OutputPath\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Add-D365RsatWifConfigAuthorityThumbprint.Tests.ps1",
    "content": "﻿Describe \"Add-D365RsatWifConfigAuthorityThumbprint Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Add-D365RsatWifConfigAuthorityThumbprint).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter CertificateThumbprint' {\n\t\t\t$parameter = (Get-Command Add-D365RsatWifConfigAuthorityThumbprint).Parameters['CertificateThumbprint']\n\t\t\t$parameter.Name | Should -Be 'CertificateThumbprint'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -CertificateThumbprint\n\t\t__AllParameterSets -CertificateThumbprint\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Add-D365WindowsDefenderRules.Tests.ps1",
    "content": "﻿Describe \"Add-D365WindowsDefenderRules Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Add-D365WindowsDefenderRules).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Silent' {\n\t\t\t$parameter = (Get-Command Add-D365WindowsDefenderRules).Parameters['Silent']\n\t\t\t$parameter.Name | Should -Be 'Silent'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Silent\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Backup-D365DevConfig.Tests.ps1",
    "content": "﻿Describe \"Backup-D365DevConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Backup-D365DevConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Backup-D365DevConfig).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Backup-D365DevConfig).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -Force\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Backup-D365MetaDataDir.Tests.ps1",
    "content": "﻿Describe \"Backup-D365MetaDataDir Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Backup-D365MetaDataDir).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command Backup-D365MetaDataDir).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BackupDir' {\n\t\t\t$parameter = (Get-Command Backup-D365MetaDataDir).Parameters['BackupDir']\n\t\t\t$parameter.Name | Should -Be 'BackupDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -MetaDataDir -BackupDir\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Backup-D365Runbook.Tests.ps1",
    "content": "﻿Describe \"Backup-D365Runbook Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Backup-D365Runbook).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter File' {\n\t\t\t$parameter = (Get-Command Backup-D365Runbook).Parameters['File']\n\t\t\t$parameter.Name | Should -Be 'File'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DestinationPath' {\n\t\t\t$parameter = (Get-Command Backup-D365Runbook).Parameters['DestinationPath']\n\t\t\t$parameter.Name | Should -Be 'DestinationPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Backup-D365Runbook).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -File\n\t\t__AllParameterSets -File -DestinationPath -Force\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Backup-D365WebConfig.Tests.ps1",
    "content": "﻿Describe \"Backup-D365WebConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Backup-D365WebConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Backup-D365WebConfig).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Backup-D365WebConfig).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -Force\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Backup-D365WifConfig.Tests.ps1",
    "content": "﻿Describe \"Backup-D365WifConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Backup-D365WifConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Backup-D365WifConfig).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Backup-D365WifConfig).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -Force\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Clear-D365ActiveBroadcastMessageConfig.Tests.ps1",
    "content": "﻿Describe \"Clear-D365ActiveBroadcastMessageConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Clear-D365ActiveBroadcastMessageConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Temporary' {\n\t\t\t$parameter = (Get-Command Clear-D365ActiveBroadcastMessageConfig).Parameters['Temporary']\n\t\t\t$parameter.Name | Should -Be 'Temporary'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Temporary\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Clear-D365BacpacObject.Tests.ps1",
    "content": "﻿Describe \"Clear-D365BacpacObject Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Clear-D365BacpacObject).ParameterSets.Name | Should -Be 'Copy', 'Keep'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Clear-D365BacpacObject).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Clear-D365BacpacObject).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ObjectType' {\n\t\t\t$parameter = (Get-Command Clear-D365BacpacObject).Parameters['ObjectType']\n\t\t\t$parameter.Name | Should -Be 'ObjectType'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Clear-D365BacpacObject).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Copy'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Copy'\n\t\t\t$parameter.ParameterSets['Copy'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Copy'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Copy'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Copy'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Copy'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ClearFromSource' {\n\t\t\t$parameter = (Get-Command Clear-D365BacpacObject).Parameters['ClearFromSource']\n\t\t\t$parameter.Name | Should -Be 'ClearFromSource'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Keep'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Keep'\n\t\t\t$parameter.ParameterSets['Keep'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Keep'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Keep'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Keep'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Keep'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Copy\" {\n\t\t<#\n\t\tCopy -Path -Name -OutputPath\n\t\tCopy -Path -Name -ObjectType -OutputPath\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Keep\" {\n\t\t<#\n\t\tKeep -Path -Name -ClearFromSource\n\t\tKeep -Path -Name -ObjectType -ClearFromSource\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Clear-D365BacpacTableData.Tests.ps1",
    "content": "﻿Describe \"Clear-D365BacpacTableData Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Clear-D365BacpacTableData).ParameterSets.Name | Should -Be 'Copy', 'Keep'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Clear-D365BacpacTableData).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Table' {\n\t\t\t$parameter = (Get-Command Clear-D365BacpacTableData).Parameters['Table']\n\t\t\t$parameter.Name | Should -Be 'Table'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Clear-D365BacpacTableData).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Copy'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Copy'\n\t\t\t$parameter.ParameterSets['Copy'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Copy'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Copy'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Copy'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Copy'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ClearFromSource' {\n\t\t\t$parameter = (Get-Command Clear-D365BacpacTableData).Parameters['ClearFromSource']\n\t\t\t$parameter.Name | Should -Be 'ClearFromSource'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Keep'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Keep'\n\t\t\t$parameter.ParameterSets['Keep'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Keep'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Keep'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Keep'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Keep'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Copy\" {\n\t\t<#\n\t\tCopy -Path -Table -OutputPath\n\t\tCopy -Path -Table -OutputPath\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Keep\" {\n\t\t<#\n\t\tKeep -Path -Table -ClearFromSource\n\t\tKeep -Path -Table -ClearFromSource\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Clear-D365MonitorData.Tests.ps1",
    "content": "﻿Describe \"Clear-D365MonitorData Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Clear-D365MonitorData).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Clear-D365MonitorData).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Path\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Clear-D365TempDbTables.Tests.ps1",
    "content": "﻿Describe \"Clear-D365TempDbTables Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Clear-D365TempDbTables).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Clear-D365TempDbTables).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Clear-D365TempDbTables).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Clear-D365TempDbTables).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Clear-D365TempDbTables).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Days' {\n\t\t\t$parameter = (Get-Command Clear-D365TempDbTables).Parameters['Days']\n\t\t\t$parameter.Name | Should -Be 'Days'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Clear-D365TempDbTables).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -Days -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/ConvertTo-D365Dacpac.Tests.ps1",
    "content": "﻿Describe \"ConvertTo-D365Dacpac Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command ConvertTo-D365Dacpac).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command ConvertTo-D365Dacpac).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path\n\t\t__AllParameterSets -Path\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Disable-D365Exception.Tests.ps1",
    "content": "﻿Describe \"Disable-D365Exception Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Disable-D365Exception).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Disable-D365Flight.Tests.ps1",
    "content": "﻿Describe \"Disable-D365Flight Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Disable-D365Flight).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter FlightName' {\n\t\t\t$parameter = (Get-Command Disable-D365Flight).Parameters['FlightName']\n\t\t\t$parameter.Name | Should -Be 'FlightName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Disable-D365Flight).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Disable-D365Flight).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Disable-D365Flight).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Disable-D365Flight).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -FlightName\n\t\t__AllParameterSets -FlightName -DatabaseServer -DatabaseName -SqlUser -SqlPwd\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Disable-D365IISPreload.Tests.ps1",
    "content": "﻿Describe \"Disable-D365IISPreload Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Disable-D365IISPreload).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Disable-D365MaintenanceMode.Tests.ps1",
    "content": "﻿Describe \"Disable-D365MaintenanceMode Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Disable-D365MaintenanceMode).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -MetaDataDir -BinDir -DatabaseServer -DatabaseName -SqlUser -SqlPwd -LogPath -ShowOriginalProgress -OutputCommandOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Disable-D365SqlChangeTracking.Tests.ps1",
    "content": "﻿Describe \"Disable-D365SqlChangeTracking Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Disable-D365SqlChangeTracking).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Disable-D365SqlChangeTracking).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Disable-D365SqlChangeTracking).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Disable-D365SqlChangeTracking).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Disable-D365SqlChangeTracking).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Disable-D365SqlChangeTracking).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Disable-D365User.Tests.ps1",
    "content": "﻿Describe \"Disable-D365User Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Disable-D365User).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Disable-D365User).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Disable-D365User).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Disable-D365User).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Disable-D365User).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Email' {\n\t\t\t$parameter = (Get-Command Disable-D365User).Parameters['Email']\n\t\t\t$parameter.Name | Should -Be 'Email'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -Email\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Enable-D365Exception.Tests.ps1",
    "content": "﻿Describe \"Enable-D365Exception Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Enable-D365Exception).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Enable-D365Flight.Tests.ps1",
    "content": "﻿Describe \"Enable-D365Flight Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Enable-D365Flight).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter FlightName' {\n\t\t\t$parameter = (Get-Command Enable-D365Flight).Parameters['FlightName']\n\t\t\t$parameter.Name | Should -Be 'FlightName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Enable-D365Flight).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Enable-D365Flight).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Enable-D365Flight).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Enable-D365Flight).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -FlightName\n\t\t__AllParameterSets -FlightName -DatabaseServer -DatabaseName -SqlUser -SqlPwd\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Enable-D365IISPreload.Tests.ps1",
    "content": "﻿Describe \"Enable-D365IISPreload Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Enable-D365IISPreload).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter BaseUrl' {\n\t\t\t$parameter = (Get-Command Enable-D365IISPreload).Parameters['BaseUrl']\n\t\t\t$parameter.Name | Should -Be 'BaseUrl'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -BaseUrl\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Enable-D365MaintenanceMode.Tests.ps1",
    "content": "﻿Describe \"Enable-D365MaintenanceMode Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Enable-D365MaintenanceMode).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -MetaDataDir -BinDir -DatabaseServer -DatabaseName -SqlUser -SqlPwd -LogPath -ShowOriginalProgress -OutputCommandOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Enable-D365SqlChangeTracking.Tests.ps1",
    "content": "﻿Describe \"Enable-D365SqlChangeTracking Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Enable-D365SqlChangeTracking).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Enable-D365SqlChangeTracking).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Enable-D365SqlChangeTracking).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Enable-D365SqlChangeTracking).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Enable-D365SqlChangeTracking).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Enable-D365SqlChangeTracking).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Enable-D365User.Tests.ps1",
    "content": "﻿Describe \"Enable-D365User Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Enable-D365User).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Enable-D365User).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Enable-D365User).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Enable-D365User).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Enable-D365User).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Email' {\n\t\t\t$parameter = (Get-Command Enable-D365User).Parameters['Email']\n\t\t\t$parameter.Name | Should -Be 'Email'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -Email\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Export-D365BacpacModelFile.Tests.ps1",
    "content": "﻿Describe \"Export-D365BacpacModelFile Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Export-D365BacpacModelFile).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Export-D365BacpacModelFile).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Export-D365BacpacModelFile).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Export-D365BacpacModelFile).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path\n\t\t__AllParameterSets -Path -OutputPath -Force\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Export-D365Model.Tests.ps1",
    "content": "﻿Describe \"Export-D365Model Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Export-D365Model).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Export-D365Model).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Model' {\n\t\t\t$parameter = (Get-Command Export-D365Model).Parameters['Model']\n\t\t\t$parameter.Name | Should -Be 'Model'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Export-D365Model).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Export-D365Model).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command Export-D365Model).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Export-D365Model).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Export-D365Model).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Export-D365Model).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path -Model\n\t\t__AllParameterSets -Path -Model -Force -BinDir -MetaDataDir -LogPath -ShowOriginalProgress -OutputCommandOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Export-D365SecurityDetails.Tests.ps1",
    "content": "﻿Describe \"Export-D365SecurityDetails Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Export-D365SecurityDetails).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter FilePath' {\n\t\t\t$parameter = (Get-Command Export-D365SecurityDetails).Parameters['FilePath']\n\t\t\t$parameter.Name | Should -Be 'FilePath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputDirectory' {\n\t\t\t$parameter = (Get-Command Export-D365SecurityDetails).Parameters['OutputDirectory']\n\t\t\t$parameter.Name | Should -Be 'OutputDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -FilePath\n\t\t__AllParameterSets -FilePath -OutputDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Find-D365Command.Tests.ps1",
    "content": "﻿Describe \"Find-D365Command Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Find-D365Command).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Pattern' {\n\t\t\t$parameter = (Get-Command Find-D365Command).Parameters['Pattern']\n\t\t\t$parameter.Name | Should -Be 'Pattern'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Tag' {\n\t\t\t$parameter = (Get-Command Find-D365Command).Parameters['Tag']\n\t\t\t$parameter.Name | Should -Be 'Tag'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Author' {\n\t\t\t$parameter = (Get-Command Find-D365Command).Parameters['Author']\n\t\t\t$parameter.Name | Should -Be 'Author'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MinimumVersion' {\n\t\t\t$parameter = (Get-Command Find-D365Command).Parameters['MinimumVersion']\n\t\t\t$parameter.Name | Should -Be 'MinimumVersion'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MaximumVersion' {\n\t\t\t$parameter = (Get-Command Find-D365Command).Parameters['MaximumVersion']\n\t\t\t$parameter.Name | Should -Be 'MaximumVersion'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Rebuild' {\n\t\t\t$parameter = (Get-Command Find-D365Command).Parameters['Rebuild']\n\t\t\t$parameter.Name | Should -Be 'Rebuild'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Find-D365Command).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Pattern -Tag -Author -MinimumVersion -MaximumVersion -Rebuild -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365AOTObject.Tests.ps1",
    "content": "﻿Describe \"Get-D365AOTObject Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365AOTObject).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Get-D365AOTObject).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ObjectType' {\n\t\t\t$parameter = (Get-Command Get-D365AOTObject).Parameters['ObjectType']\n\t\t\t$parameter.Name | Should -Be 'ObjectType'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365AOTObject).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SearchInPackages' {\n\t\t\t$parameter = (Get-Command Get-D365AOTObject).Parameters['SearchInPackages']\n\t\t\t$parameter.Name | Should -Be 'SearchInPackages'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter IncludePath' {\n\t\t\t$parameter = (Get-Command Get-D365AOTObject).Parameters['IncludePath']\n\t\t\t$parameter.Name | Should -Be 'IncludePath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path\n\t\t__AllParameterSets -Path -ObjectType -Name -SearchInPackages -IncludePath\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365ActiveAzureStorageConfig.Tests.ps1",
    "content": "﻿Describe \"Get-D365ActiveAzureStorageConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365ActiveAzureStorageConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputAsPsCustomObject' {\n\t\t\t$parameter = (Get-Command Get-D365ActiveAzureStorageConfig).Parameters['OutputAsPsCustomObject']\n\t\t\t$parameter.Name | Should -Be 'OutputAsPsCustomObject'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputAsPsCustomObject\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365ActiveBroadcastMessageConfig.Tests.ps1",
    "content": "﻿Describe \"Get-D365ActiveBroadcastMessageConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365ActiveBroadcastMessageConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputAsHashtable' {\n\t\t\t$parameter = (Get-Command Get-D365ActiveBroadcastMessageConfig).Parameters['OutputAsHashtable']\n\t\t\t$parameter.Name | Should -Be 'OutputAsHashtable'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputAsHashtable\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365AzureDevOpsNuget.Tests.ps1",
    "content": "﻿Describe \"Get-D365AzureDevOpsNuget Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365AzureDevOpsNuget).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Url' {\n\t\t\t$parameter = (Get-Command Get-D365AzureDevOpsNuget).Parameters['Url']\n\t\t\t$parameter.Name | Should -Be 'Url'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FeedName' {\n\t\t\t$parameter = (Get-Command Get-D365AzureDevOpsNuget).Parameters['FeedName']\n\t\t\t$parameter.Name | Should -Be 'FeedName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PeronalAccessToken' {\n\t\t\t$parameter = (Get-Command Get-D365AzureDevOpsNuget).Parameters['PeronalAccessToken']\n\t\t\t$parameter.Name | Should -Be 'PeronalAccessToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365AzureDevOpsNuget).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Latest' {\n\t\t\t$parameter = (Get-Command Get-D365AzureDevOpsNuget).Parameters['Latest']\n\t\t\t$parameter.Name | Should -Be 'Latest'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Url -FeedName -PeronalAccessToken\n\t\t__AllParameterSets -Url -FeedName -PeronalAccessToken -Name -Latest\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365AzureStorageConfig.Tests.ps1",
    "content": "﻿Describe \"Get-D365AzureStorageConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365AzureStorageConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365AzureStorageConfig).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputAsHashtable' {\n\t\t\t$parameter = (Get-Command Get-D365AzureStorageConfig).Parameters['OutputAsHashtable']\n\t\t\t$parameter.Name | Should -Be 'OutputAsHashtable'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Name -OutputAsHashtable\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365AzureStorageFile.Tests.ps1",
    "content": "﻿Describe \"Get-D365AzureStorageFile Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365AzureStorageFile).ParameterSets.Name | Should -Be 'Default', 'Latest'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter AccountId' {\n\t\t\t$parameter = (Get-Command Get-D365AzureStorageFile).Parameters['AccountId']\n\t\t\t$parameter.Name | Should -Be 'AccountId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AccessToken' {\n\t\t\t$parameter = (Get-Command Get-D365AzureStorageFile).Parameters['AccessToken']\n\t\t\t$parameter.Name | Should -Be 'AccessToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SAS' {\n\t\t\t$parameter = (Get-Command Get-D365AzureStorageFile).Parameters['SAS']\n\t\t\t$parameter.Name | Should -Be 'SAS'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Container' {\n\t\t\t$parameter = (Get-Command Get-D365AzureStorageFile).Parameters['Container']\n\t\t\t$parameter.Name | Should -Be 'Container'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365AzureStorageFile).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Latest' {\n\t\t\t$parameter = (Get-Command Get-D365AzureStorageFile).Parameters['Latest']\n\t\t\t$parameter.Name | Should -Be 'Latest'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Latest'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Latest'\n\t\t\t$parameter.ParameterSets['Latest'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Latest'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Latest'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Latest'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Latest'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -AccountId -AccessToken -SAS -Container -Name\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Latest\" {\n\t\t<#\n\t\tLatest -Latest\n\t\tLatest -AccountId -AccessToken -SAS -Container -Latest\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365AzureStorageUrl.Tests.ps1",
    "content": "﻿Describe \"Get-D365AzureStorageUrl Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365AzureStorageUrl).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter AccountId' {\n\t\t\t$parameter = (Get-Command Get-D365AzureStorageUrl).Parameters['AccountId']\n\t\t\t$parameter.Name | Should -Be 'AccountId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SAS' {\n\t\t\t$parameter = (Get-Command Get-D365AzureStorageUrl).Parameters['SAS']\n\t\t\t$parameter.Name | Should -Be 'SAS'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Container' {\n\t\t\t$parameter = (Get-Command Get-D365AzureStorageUrl).Parameters['Container']\n\t\t\t$parameter.Name | Should -Be 'Container'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputAsHashtable' {\n\t\t\t$parameter = (Get-Command Get-D365AzureStorageUrl).Parameters['OutputAsHashtable']\n\t\t\t$parameter.Name | Should -Be 'OutputAsHashtable'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -AccountId -SAS -Container -OutputAsHashtable\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365BacpacSqlOptions.Tests.ps1",
    "content": "﻿Describe \"Get-D365BacpacSqlOptions Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365BacpacSqlOptions).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Get-D365BacpacSqlOptions).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Path\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365BacpacTable.Tests.ps1",
    "content": "﻿Describe \"Get-D365BacpacTable Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365BacpacTable).ParameterSets.Name | Should -Be 'Default', 'SortSizeAsc', 'SortSizeDesc'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Get-D365BacpacTable).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Table' {\n\t\t\t$parameter = (Get-Command Get-D365BacpacTable).Parameters['Table']\n\t\t\t$parameter.Name | Should -Be 'Table'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Top' {\n\t\t\t$parameter = (Get-Command Get-D365BacpacTable).Parameters['Top']\n\t\t\t$parameter.Name | Should -Be 'Top'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SortSizeAsc' {\n\t\t\t$parameter = (Get-Command Get-D365BacpacTable).Parameters['SortSizeAsc']\n\t\t\t$parameter.Name | Should -Be 'SortSizeAsc'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'SortSizeAsc'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'SortSizeAsc'\n\t\t\t$parameter.ParameterSets['SortSizeAsc'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['SortSizeAsc'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['SortSizeAsc'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['SortSizeAsc'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['SortSizeAsc'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SortSizeDesc' {\n\t\t\t$parameter = (Get-Command Get-D365BacpacTable).Parameters['SortSizeDesc']\n\t\t\t$parameter.Name | Should -Be 'SortSizeDesc'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'SortSizeDesc'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'SortSizeDesc'\n\t\t\t$parameter.ParameterSets['SortSizeDesc'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['SortSizeDesc'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['SortSizeDesc'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['SortSizeDesc'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['SortSizeDesc'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -Path\n\t\tDefault -Path -Table -Top\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset SortSizeAsc\" {\n\t\t<#\n\t\tSortSizeAsc -Path\n\t\tSortSizeAsc -Path -Table -Top -SortSizeAsc\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset SortSizeDesc\" {\n\t\t<#\n\t\tSortSizeDesc -Path\n\t\tSortSizeDesc -Path -Table -Top -SortSizeDesc\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365BroadcastMessage.Tests.ps1",
    "content": "﻿Describe \"Get-D365BroadcastMessage Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365BroadcastMessage).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Get-D365BroadcastMessage).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Get-D365BroadcastMessage).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Get-D365BroadcastMessage).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Get-D365BroadcastMessage).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ExcludeExpired' {\n\t\t\t$parameter = (Get-Command Get-D365BroadcastMessage).Parameters['ExcludeExpired']\n\t\t\t$parameter.Name | Should -Be 'ExcludeExpired'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -ExcludeExpired\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365BroadcastMessageConfig.Tests.ps1",
    "content": "﻿Describe \"Get-D365BroadcastMessageConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365BroadcastMessageConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365BroadcastMessageConfig).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputAsHashtable' {\n\t\t\t$parameter = (Get-Command Get-D365BroadcastMessageConfig).Parameters['OutputAsHashtable']\n\t\t\t$parameter.Name | Should -Be 'OutputAsHashtable'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Name -OutputAsHashtable\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365ClickOnceTrustPrompt.Tests.ps1",
    "content": "﻿Describe \"Get-D365ClickOnceTrustPrompt Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365ClickOnceTrustPrompt).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365CompilerResult.Tests.ps1",
    "content": "﻿Describe \"Get-D365CompilerResult Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365CompilerResult).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Get-D365CompilerResult).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ErrorsOnly' {\n\t\t\t$parameter = (Get-Command Get-D365CompilerResult).Parameters['ErrorsOnly']\n\t\t\t$parameter.Name | Should -Be 'ErrorsOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputTotals' {\n\t\t\t$parameter = (Get-Command Get-D365CompilerResult).Parameters['OutputTotals']\n\t\t\t$parameter.Name | Should -Be 'OutputTotals'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputAsObjects' {\n\t\t\t$parameter = (Get-Command Get-D365CompilerResult).Parameters['OutputAsObjects']\n\t\t\t$parameter.Name | Should -Be 'OutputAsObjects'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path\n\t\t__AllParameterSets -Path -ErrorsOnly -OutputTotals -OutputAsObjects\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365Database.Tests.ps1",
    "content": "﻿Describe \"Get-D365Database Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365Database).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365Database).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Get-D365Database).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Get-D365Database).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Get-D365Database).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Get-D365Database).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Name -DatabaseServer -DatabaseName -SqlUser -SqlPwd\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365DatabaseAccess.Tests.ps1",
    "content": "﻿Describe \"Get-D365DatabaseAccess Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365DatabaseAccess).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365DecryptedWebConfig.Tests.ps1",
    "content": "﻿Describe \"Get-D365DecryptedWebConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365DecryptedWebConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Get-D365DecryptedWebConfig).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AosServiceWebRootPath' {\n\t\t\t$parameter = (Get-Command Get-D365DecryptedWebConfig).Parameters['AosServiceWebRootPath']\n\t\t\t$parameter.Name | Should -Be 'AosServiceWebRootPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -AosServiceWebRootPath\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365DefaultModelForNewProjects.Tests.ps1",
    "content": "﻿Describe \"Get-D365DefaultModelForNewProjects Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365DefaultModelForNewProjects).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365DotNetClass.Tests.ps1",
    "content": "﻿Describe \"Get-D365DotNetClass Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365DotNetClass).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365DotNetClass).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Assembly' {\n\t\t\t$parameter = (Get-Command Get-D365DotNetClass).Parameters['Assembly']\n\t\t\t$parameter.Name | Should -Be 'Assembly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Get-D365DotNetClass).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -Name -Assembly -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365DotNetMethod.Tests.ps1",
    "content": "﻿Describe \"Get-D365DotNetMethod Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365DotNetMethod).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Assembly' {\n\t\t\t$parameter = (Get-Command Get-D365DotNetMethod).Parameters['Assembly']\n\t\t\t$parameter.Name | Should -Be 'Assembly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365DotNetMethod).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter TypeName' {\n\t\t\t$parameter = (Get-Command Get-D365DotNetMethod).Parameters['TypeName']\n\t\t\t$parameter.Name | Should -Be 'TypeName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -Assembly\n\t\tDefault -Assembly -Name -TypeName\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365Environment.Tests.ps1",
    "content": "﻿Describe \"Get-D365Environment Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365Environment).ParameterSets.Name | Should -Be 'Default', 'Specific'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ComputerName' {\n\t\t\t$parameter = (Get-Command Get-D365Environment).Parameters['ComputerName']\n\t\t\t$parameter.Name | Should -Be 'ComputerName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific', 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter All' {\n\t\t\t$parameter = (Get-Command Get-D365Environment).Parameters['All']\n\t\t\t$parameter.Name | Should -Be 'All'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Aos' {\n\t\t\t$parameter = (Get-Command Get-D365Environment).Parameters['Aos']\n\t\t\t$parameter.Name | Should -Be 'Aos'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Batch' {\n\t\t\t$parameter = (Get-Command Get-D365Environment).Parameters['Batch']\n\t\t\t$parameter.Name | Should -Be 'Batch'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FinancialReporter' {\n\t\t\t$parameter = (Get-Command Get-D365Environment).Parameters['FinancialReporter']\n\t\t\t$parameter.Name | Should -Be 'FinancialReporter'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DMF' {\n\t\t\t$parameter = (Get-Command Get-D365Environment).Parameters['DMF']\n\t\t\t$parameter.Name | Should -Be 'DMF'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OnlyStartTypeAutomatic' {\n\t\t\t$parameter = (Get-Command Get-D365Environment).Parameters['OnlyStartTypeAutomatic']\n\t\t\t$parameter.Name | Should -Be 'OnlyStartTypeAutomatic'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputServiceDetailsOnly' {\n\t\t\t$parameter = (Get-Command Get-D365Environment).Parameters['OutputServiceDetailsOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputServiceDetailsOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -ComputerName -All -OnlyStartTypeAutomatic -OutputServiceDetailsOnly\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Specific\" {\n\t\t<#\n\t\tSpecific -\n\t\tSpecific -ComputerName -Aos -Batch -FinancialReporter -DMF -OnlyStartTypeAutomatic -OutputServiceDetailsOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365EnvironmentSettings.Tests.ps1",
    "content": "﻿Describe \"Get-D365EnvironmentSettings Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365EnvironmentSettings).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365EventTraceProvider.Tests.ps1",
    "content": "﻿Describe \"Get-D365EventTraceProvider Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365EventTraceProvider).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365EventTraceProvider).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Name\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365ExternalIP.Tests.ps1",
    "content": "﻿Describe \"Get-D365ExternalIP Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365ExternalIP).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter SaveToClipboard' {\n\t\t\t$parameter = (Get-Command Get-D365ExternalIP).Parameters['SaveToClipboard']\n\t\t\t$parameter.Name | Should -Be 'SaveToClipboard'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -SaveToClipboard\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365Flight.Tests.ps1",
    "content": "﻿Describe \"Get-D365Flight Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365Flight).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter FlightName' {\n\t\t\t$parameter = (Get-Command Get-D365Flight).Parameters['FlightName']\n\t\t\t$parameter.Name | Should -Be 'FlightName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Get-D365Flight).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Get-D365Flight).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Get-D365Flight).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Get-D365Flight).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -FlightName -DatabaseServer -DatabaseName -SqlUser -SqlPwd\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365IISPreload.Tests.ps1",
    "content": "﻿Describe \"Get-D365IISPreload Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365IISPreload).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365InstalledHotfix.Tests.ps1",
    "content": "﻿Describe \"Get-D365InstalledHotfix Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365InstalledHotfix).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Get-D365InstalledHotfix).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Get-D365InstalledHotfix).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Model' {\n\t\t\t$parameter = (Get-Command Get-D365InstalledHotfix).Parameters['Model']\n\t\t\t$parameter.Name | Should -Be 'Model'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365InstalledHotfix).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter KB' {\n\t\t\t$parameter = (Get-Command Get-D365InstalledHotfix).Parameters['KB']\n\t\t\t$parameter.Name | Should -Be 'KB'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -BinDir -PackageDirectory -Model -Name -KB\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365InstalledPackage.Tests.ps1",
    "content": "﻿Describe \"Get-D365InstalledPackage Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365InstalledPackage).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365InstalledPackage).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Get-D365InstalledPackage).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Name -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365InstalledService.Tests.ps1",
    "content": "﻿Describe \"Get-D365InstalledService Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365InstalledService).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Get-D365InstalledService).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -Path\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365InstanceName.Tests.ps1",
    "content": "﻿Describe \"Get-D365InstanceName Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365InstanceName).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365JsonService.Tests.ps1",
    "content": "﻿Describe \"Get-D365JsonService Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365JsonService).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365JsonService).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Url' {\n\t\t\t$parameter = (Get-Command Get-D365JsonService).Parameters['Url']\n\t\t\t$parameter.Name | Should -Be 'Url'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Tenant' {\n\t\t\t$parameter = (Get-Command Get-D365JsonService).Parameters['Tenant']\n\t\t\t$parameter.Name | Should -Be 'Tenant'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ClientId' {\n\t\t\t$parameter = (Get-Command Get-D365JsonService).Parameters['ClientId']\n\t\t\t$parameter.Name | Should -Be 'ClientId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ClientSecret' {\n\t\t\t$parameter = (Get-Command Get-D365JsonService).Parameters['ClientSecret']\n\t\t\t$parameter.Name | Should -Be 'ClientSecret'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RawOutput' {\n\t\t\t$parameter = (Get-Command Get-D365JsonService).Parameters['RawOutput']\n\t\t\t$parameter.Name | Should -Be 'RawOutput'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputAsJson' {\n\t\t\t$parameter = (Get-Command Get-D365JsonService).Parameters['OutputAsJson']\n\t\t\t$parameter.Name | Should -Be 'OutputAsJson'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Url -Tenant -ClientId -ClientSecret\n\t\t__AllParameterSets -Name -Url -Tenant -ClientId -ClientSecret -RawOutput -OutputAsJson\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365Label.Tests.ps1",
    "content": "﻿Describe \"Get-D365Label Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365Label).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Get-D365Label).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LabelFileId' {\n\t\t\t$parameter = (Get-Command Get-D365Label).Parameters['LabelFileId']\n\t\t\t$parameter.Name | Should -Be 'LabelFileId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Language' {\n\t\t\t$parameter = (Get-Command Get-D365Label).Parameters['Language']\n\t\t\t$parameter.Name | Should -Be 'Language'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365Label).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -LabelFileId\n\t\tDefault -BinDir -LabelFileId -Language -Name\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365LabelFile.Tests.ps1",
    "content": "﻿Describe \"Get-D365LabelFile Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365LabelFile).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Get-D365LabelFile).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Get-D365LabelFile).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Module' {\n\t\t\t$parameter = (Get-Command Get-D365LabelFile).Parameters['Module']\n\t\t\t$parameter.Name | Should -Be 'Module'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365LabelFile).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -BinDir -PackageDirectory -Module -Name\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365Language.Tests.ps1",
    "content": "﻿Describe \"Get-D365Language Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365Language).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Get-D365Language).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365Language).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -BinDir -Name\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365LcsApiConfig.Tests.ps1",
    "content": "﻿Describe \"Get-D365LcsApiConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365LcsApiConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputAsHashtable' {\n\t\t\t$parameter = (Get-Command Get-D365LcsApiConfig).Parameters['OutputAsHashtable']\n\t\t\t$parameter.Name | Should -Be 'OutputAsHashtable'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputAsHashtable\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365LcsApiToken.Tests.ps1",
    "content": "﻿Describe \"Get-D365LcsApiToken Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365LcsApiToken).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ClientId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsApiToken).Parameters['ClientId']\n\t\t\t$parameter.Name | Should -Be 'ClientId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Username' {\n\t\t\t$parameter = (Get-Command Get-D365LcsApiToken).Parameters['Username']\n\t\t\t$parameter.Name | Should -Be 'Username'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Password' {\n\t\t\t$parameter = (Get-Command Get-D365LcsApiToken).Parameters['Password']\n\t\t\t$parameter.Name | Should -Be 'Password'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Get-D365LcsApiToken).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Get-D365LcsApiToken).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Username -Password\n\t\t__AllParameterSets -ClientId -Username -Password -LcsApiUri -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365LcsAssetFile.Tests.ps1",
    "content": "﻿Describe \"Get-D365LcsAssetFile Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365LcsAssetFile).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetFile).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FileType' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetFile).Parameters['FileType']\n\t\t\t$parameter.Name | Should -Be 'FileType'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be LcsAssetFileType\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AssetName' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetFile).Parameters['AssetName']\n\t\t\t$parameter.Name | Should -Be 'AssetName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AssetVersion' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetFile).Parameters['AssetVersion']\n\t\t\t$parameter.Name | Should -Be 'AssetVersion'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AssetFilename' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetFile).Parameters['AssetFilename']\n\t\t\t$parameter.Name | Should -Be 'AssetFilename'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AssetDescription' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetFile).Parameters['AssetDescription']\n\t\t\t$parameter.Name | Should -Be 'AssetDescription'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AssetId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetFile).Parameters['AssetId']\n\t\t\t$parameter.Name | Should -Be 'AssetId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetFile).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetFile).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Latest' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetFile).Parameters['Latest']\n\t\t\t$parameter.Name | Should -Be 'Latest'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RetryTimeout' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetFile).Parameters['RetryTimeout']\n\t\t\t$parameter.Name | Should -Be 'RetryTimeout'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.TimeSpan\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 9\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetFile).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -ProjectId -FileType -AssetName -AssetVersion -AssetFilename -AssetDescription -AssetId -BearerToken -LcsApiUri -Latest -RetryTimeout -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365LcsAssetValidationStatus.Tests.ps1",
    "content": "﻿Describe \"Get-D365LcsAssetValidationStatus Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365LcsAssetValidationStatus).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter AssetId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetValidationStatus).Parameters['AssetId']\n\t\t\t$parameter.Name | Should -Be 'AssetId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetValidationStatus).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetValidationStatus).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetValidationStatus).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter WaitForValidation' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetValidationStatus).Parameters['WaitForValidation']\n\t\t\t$parameter.Name | Should -Be 'WaitForValidation'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SleepInSeconds' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetValidationStatus).Parameters['SleepInSeconds']\n\t\t\t$parameter.Name | Should -Be 'SleepInSeconds'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RetryTimeout' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetValidationStatus).Parameters['RetryTimeout']\n\t\t\t$parameter.Name | Should -Be 'RetryTimeout'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.TimeSpan\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Get-D365LcsAssetValidationStatus).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -AssetId\n\t\t__AllParameterSets -AssetId -ProjectId -BearerToken -LcsApiUri -WaitForValidation -SleepInSeconds -RetryTimeout -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365LcsDatabaseBackups.Tests.ps1",
    "content": "﻿Describe \"Get-D365LcsDatabaseBackups Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365LcsDatabaseBackups).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDatabaseBackups).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDatabaseBackups).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDatabaseBackups).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Latest' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDatabaseBackups).Parameters['Latest']\n\t\t\t$parameter.Name | Should -Be 'Latest'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RetryTimeout' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDatabaseBackups).Parameters['RetryTimeout']\n\t\t\t$parameter.Name | Should -Be 'RetryTimeout'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.TimeSpan\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDatabaseBackups).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -ProjectId -BearerToken -LcsApiUri -Latest -RetryTimeout -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365LcsDatabaseOperationStatus.Tests.ps1",
    "content": "﻿Describe \"Get-D365LcsDatabaseOperationStatus Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365LcsDatabaseOperationStatus).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OperationActivityId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['OperationActivityId']\n\t\t\t$parameter.Name | Should -Be 'OperationActivityId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnvironmentId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['EnvironmentId']\n\t\t\t$parameter.Name | Should -Be 'EnvironmentId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter WaitForCompletion' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['WaitForCompletion']\n\t\t\t$parameter.Name | Should -Be 'WaitForCompletion'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SleepInSeconds' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['SleepInSeconds']\n\t\t\t$parameter.Name | Should -Be 'SleepInSeconds'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RetryTimeout' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['RetryTimeout']\n\t\t\t$parameter.Name | Should -Be 'RetryTimeout'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.TimeSpan\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -OperationActivityId -EnvironmentId\n\t\t__AllParameterSets -ProjectId -BearerToken -OperationActivityId -EnvironmentId -LcsApiUri -WaitForCompletion -SleepInSeconds -RetryTimeout -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365LcsDeploymentStatus.Tests.ps1",
    "content": "﻿Describe \"Get-D365LcsDeploymentStatus Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365LcsDeploymentStatus).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ActivityId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['ActivityId']\n\t\t\t$parameter.Name | Should -Be 'ActivityId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnvironmentId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['EnvironmentId']\n\t\t\t$parameter.Name | Should -Be 'EnvironmentId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter WaitForCompletion' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['WaitForCompletion']\n\t\t\t$parameter.Name | Should -Be 'WaitForCompletion'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SleepInSeconds' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['SleepInSeconds']\n\t\t\t$parameter.Name | Should -Be 'SleepInSeconds'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FailOnErrorMessage' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['FailOnErrorMessage']\n\t\t\t$parameter.Name | Should -Be 'FailOnErrorMessage'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RetryTimeout' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['RetryTimeout']\n\t\t\t$parameter.Name | Should -Be 'RetryTimeout'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.TimeSpan\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -ActivityId -EnvironmentId\n\t\t__AllParameterSets -ProjectId -BearerToken -ActivityId -EnvironmentId -LcsApiUri -WaitForCompletion -SleepInSeconds -FailOnErrorMessage -RetryTimeout -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365LcsEnvironmentHistory.Tests.ps1",
    "content": "﻿Describe \"Get-D365LcsEnvironmentHistory Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365LcsEnvironmentHistory).ParameterSets.Name | Should -Be 'Default', 'Pagination'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnvironmentId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['EnvironmentId']\n\t\t\t$parameter.Name | Should -Be 'EnvironmentId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter TraverseAllPages' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['TraverseAllPages']\n\t\t\t$parameter.Name | Should -Be 'TraverseAllPages'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Pagination'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Pagination'\n\t\t\t$parameter.ParameterSets['Pagination'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Pagination'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Pagination'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Pagination'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Pagination'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FirstPages' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['FirstPages']\n\t\t\t$parameter.Name | Should -Be 'FirstPages'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Pagination'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Pagination'\n\t\t\t$parameter.ParameterSets['Pagination'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Pagination'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Pagination'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Pagination'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Pagination'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FailOnErrorMessage' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['FailOnErrorMessage']\n\t\t\t$parameter.Name | Should -Be 'FailOnErrorMessage'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RetryTimeout' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['RetryTimeout']\n\t\t\t$parameter.Name | Should -Be 'RetryTimeout'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.TimeSpan\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -EnvironmentId\n\t\tDefault -ProjectId -BearerToken -EnvironmentId -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Pagination\" {\n\t\t<#\n\t\tPagination -EnvironmentId\n\t\tPagination -ProjectId -BearerToken -EnvironmentId -TraverseAllPages -FirstPages -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365LcsEnvironmentMetadata.Tests.ps1",
    "content": "﻿Describe \"Get-D365LcsEnvironmentMetadata Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365LcsEnvironmentMetadata).ParameterSets.Name | Should -Be 'Default', 'SearchByEnvironmentId', 'SearchByEnvironmentName', 'Pagination'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnvironmentId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['EnvironmentId']\n\t\t\t$parameter.Name | Should -Be 'EnvironmentId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'SearchByEnvironmentId'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'SearchByEnvironmentId'\n\t\t\t$parameter.ParameterSets['SearchByEnvironmentId'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByEnvironmentId'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['SearchByEnvironmentId'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByEnvironmentId'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByEnvironmentId'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnvironmentName' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['EnvironmentName']\n\t\t\t$parameter.Name | Should -Be 'EnvironmentName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'SearchByEnvironmentName'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'SearchByEnvironmentName'\n\t\t\t$parameter.ParameterSets['SearchByEnvironmentName'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByEnvironmentName'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['SearchByEnvironmentName'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByEnvironmentName'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByEnvironmentName'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter TraverseAllPages' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['TraverseAllPages']\n\t\t\t$parameter.Name | Should -Be 'TraverseAllPages'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Pagination'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Pagination'\n\t\t\t$parameter.ParameterSets['Pagination'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Pagination'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Pagination'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Pagination'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Pagination'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FirstPages' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['FirstPages']\n\t\t\t$parameter.Name | Should -Be 'FirstPages'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Pagination'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Pagination'\n\t\t\t$parameter.ParameterSets['Pagination'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Pagination'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Pagination'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Pagination'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Pagination'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FailOnErrorMessage' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['FailOnErrorMessage']\n\t\t\t$parameter.Name | Should -Be 'FailOnErrorMessage'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RetryTimeout' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['RetryTimeout']\n\t\t\t$parameter.Name | Should -Be 'RetryTimeout'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.TimeSpan\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -ProjectId -BearerToken -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset SearchByEnvironmentId\" {\n\t\t<#\n\t\tSearchByEnvironmentId -\n\t\tSearchByEnvironmentId -ProjectId -BearerToken -EnvironmentId -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset SearchByEnvironmentName\" {\n\t\t<#\n\t\tSearchByEnvironmentName -\n\t\tSearchByEnvironmentName -ProjectId -BearerToken -EnvironmentName -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Pagination\" {\n\t\t<#\n\t\tPagination -\n\t\tPagination -ProjectId -BearerToken -TraverseAllPages -FirstPages -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365LcsEnvironmentRsatCertificate.Tests.ps1",
    "content": "﻿Describe \"Get-D365LcsEnvironmentRsatCertificate Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365LcsEnvironmentRsatCertificate).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentRsatCertificate).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentRsatCertificate).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnvironmentId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentRsatCertificate).Parameters['EnvironmentId']\n\t\t\t$parameter.Name | Should -Be 'EnvironmentId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentRsatCertificate).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentRsatCertificate).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FailOnErrorMessage' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentRsatCertificate).Parameters['FailOnErrorMessage']\n\t\t\t$parameter.Name | Should -Be 'FailOnErrorMessage'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RetryTimeout' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentRsatCertificate).Parameters['RetryTimeout']\n\t\t\t$parameter.Name | Should -Be 'RetryTimeout'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.TimeSpan\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Get-D365LcsEnvironmentRsatCertificate).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -EnvironmentId\n\t\tDefault -ProjectId -BearerToken -EnvironmentId -OutputPath -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365LcsSharedAssetFile.Tests.ps1",
    "content": "﻿Describe \"Get-D365LcsSharedAssetFile Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365LcsSharedAssetFile).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FileType' {\n\t\t\t$parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['FileType']\n\t\t\t$parameter.Name | Should -Be 'FileType'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be LcsAssetFileType\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AssetName' {\n\t\t\t$parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['AssetName']\n\t\t\t$parameter.Name | Should -Be 'AssetName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AssetVersion' {\n\t\t\t$parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['AssetVersion']\n\t\t\t$parameter.Name | Should -Be 'AssetVersion'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AssetFilename' {\n\t\t\t$parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['AssetFilename']\n\t\t\t$parameter.Name | Should -Be 'AssetFilename'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AssetDescription' {\n\t\t\t$parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['AssetDescription']\n\t\t\t$parameter.Name | Should -Be 'AssetDescription'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AssetId' {\n\t\t\t$parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['AssetId']\n\t\t\t$parameter.Name | Should -Be 'AssetId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Latest' {\n\t\t\t$parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['Latest']\n\t\t\t$parameter.Name | Should -Be 'Latest'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SkipSasGeneration' {\n\t\t\t$parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['SkipSasGeneration']\n\t\t\t$parameter.Name | Should -Be 'SkipSasGeneration'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RetryTimeout' {\n\t\t\t$parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['RetryTimeout']\n\t\t\t$parameter.Name | Should -Be 'RetryTimeout'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.TimeSpan\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 9\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -ProjectId -FileType -AssetName -AssetVersion -AssetFilename -AssetDescription -AssetId -BearerToken -LcsApiUri -Latest -SkipSasGeneration -RetryTimeout -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365MaintenanceMode.Tests.ps1",
    "content": "﻿Describe \"Get-D365MaintenanceMode Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365MaintenanceMode).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Get-D365MaintenanceMode).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Get-D365MaintenanceMode).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Get-D365MaintenanceMode).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Get-D365MaintenanceMode).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -DatabaseServer -DatabaseName -SqlUser -SqlPwd\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365Model.Tests.ps1",
    "content": "﻿Describe \"Get-D365Model Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365Model).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365Model).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Module' {\n\t\t\t$parameter = (Get-Command Get-D365Model).Parameters['Module']\n\t\t\t$parameter.Name | Should -Be 'Module'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter CustomizableOnly' {\n\t\t\t$parameter = (Get-Command Get-D365Model).Parameters['CustomizableOnly']\n\t\t\t$parameter.Name | Should -Be 'CustomizableOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ExcludeMicrosoftModels' {\n\t\t\t$parameter = (Get-Command Get-D365Model).Parameters['ExcludeMicrosoftModels']\n\t\t\t$parameter.Name | Should -Be 'ExcludeMicrosoftModels'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ExcludeBinaryModels' {\n\t\t\t$parameter = (Get-Command Get-D365Model).Parameters['ExcludeBinaryModels']\n\t\t\t$parameter.Name | Should -Be 'ExcludeBinaryModels'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Get-D365Model).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Get-D365Model).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Name -Module -CustomizableOnly -ExcludeMicrosoftModels -ExcludeBinaryModels -BinDir -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365Module.Tests.ps1",
    "content": "﻿Describe \"Get-D365Module Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365Module).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365Module).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ExcludeBinaryModules' {\n\t\t\t$parameter = (Get-Command Get-D365Module).Parameters['ExcludeBinaryModules']\n\t\t\t$parameter.Name | Should -Be 'ExcludeBinaryModules'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter InDependencyOrder' {\n\t\t\t$parameter = (Get-Command Get-D365Module).Parameters['InDependencyOrder']\n\t\t\t$parameter.Name | Should -Be 'InDependencyOrder'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Get-D365Module).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Get-D365Module).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Name -ExcludeBinaryModules -InDependencyOrder -BinDir -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365OfflineAuthenticationAdminEmail.Tests.ps1",
    "content": "﻿Describe \"Get-D365OfflineAuthenticationAdminEmail Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365OfflineAuthenticationAdminEmail).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365PackageBundleDetail.Tests.ps1",
    "content": "﻿Describe \"Get-D365PackageBundleDetail Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365PackageBundleDetail).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Get-D365PackageBundleDetail).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ExtractionPath' {\n\t\t\t$parameter = (Get-Command Get-D365PackageBundleDetail).Parameters['ExtractionPath']\n\t\t\t$parameter.Name | Should -Be 'ExtractionPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter KB' {\n\t\t\t$parameter = (Get-Command Get-D365PackageBundleDetail).Parameters['KB']\n\t\t\t$parameter.Name | Should -Be 'KB'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Hotfix' {\n\t\t\t$parameter = (Get-Command Get-D365PackageBundleDetail).Parameters['Hotfix']\n\t\t\t$parameter.Name | Should -Be 'Hotfix'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Traverse' {\n\t\t\t$parameter = (Get-Command Get-D365PackageBundleDetail).Parameters['Traverse']\n\t\t\t$parameter.Name | Should -Be 'Traverse'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter KeepFiles' {\n\t\t\t$parameter = (Get-Command Get-D365PackageBundleDetail).Parameters['KeepFiles']\n\t\t\t$parameter.Name | Should -Be 'KeepFiles'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter IncludeRawManifest' {\n\t\t\t$parameter = (Get-Command Get-D365PackageBundleDetail).Parameters['IncludeRawManifest']\n\t\t\t$parameter.Name | Should -Be 'IncludeRawManifest'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path\n\t\t__AllParameterSets -Path -ExtractionPath -KB -Hotfix -Traverse -KeepFiles -IncludeRawManifest\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365PackageLabelResourceFile.Tests.ps1",
    "content": "﻿Describe \"Get-D365PackageLabelResourceFile Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365PackageLabelResourceFile).ParameterSets.Name | Should -Be 'Default', 'Specific'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Get-D365PackageLabelResourceFile).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific', 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365PackageLabelResourceFile).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Language' {\n\t\t\t$parameter = (Get-Command Get-D365PackageLabelResourceFile).Parameters['Language']\n\t\t\t$parameter.Name | Should -Be 'Language'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -PackageDirectory\n\t\tDefault -PackageDirectory -Name -Language\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Specific\" {\n\t\t<#\n\t\tSpecific -PackageDirectory\n\t\tSpecific -PackageDirectory -Name -Language\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365PackageLabelResources.Tests.ps1",
    "content": "﻿Describe \"Get-D365PackageLabelResources Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365PackageLabelResources).ParameterSets.Name | Should -Be 'Default', 'Specific'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter FilePath' {\n\t\t\t$parameter = (Get-Command Get-D365PackageLabelResources).Parameters['FilePath']\n\t\t\t$parameter.Name | Should -Be 'FilePath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific', 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365PackageLabelResources).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Value' {\n\t\t\t$parameter = (Get-Command Get-D365PackageLabelResources).Parameters['Value']\n\t\t\t$parameter.Name | Should -Be 'Value'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter IncludePath' {\n\t\t\t$parameter = (Get-Command Get-D365PackageLabelResources).Parameters['IncludePath']\n\t\t\t$parameter.Name | Should -Be 'IncludePath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -FilePath\n\t\tDefault -FilePath -Name -Value -IncludePath\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Specific\" {\n\t\t<#\n\t\tSpecific -FilePath\n\t\tSpecific -FilePath -Name -Value -IncludePath\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365ProductInformation.Tests.ps1",
    "content": "﻿Describe \"Get-D365ProductInformation Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365ProductInformation).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365RsatCertificateThumbprint.Tests.ps1",
    "content": "﻿Describe \"Get-D365RsatCertificateThumbprint Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365RsatCertificateThumbprint).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365RsatPlaybackFile.Tests.ps1",
    "content": "﻿Describe \"Get-D365RsatPlaybackFile Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365RsatPlaybackFile).ParameterSets.Name | Should -Be 'Default', 'ExecutionUser'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Get-D365RsatPlaybackFile).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365RsatPlaybackFile).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ExecutionUsername' {\n\t\t\t$parameter = (Get-Command Get-D365RsatPlaybackFile).Parameters['ExecutionUsername']\n\t\t\t$parameter.Name | Should -Be 'ExecutionUsername'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ExecutionUser'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ExecutionUser'\n\t\t\t$parameter.ParameterSets['ExecutionUser'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExecutionUser'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['ExecutionUser'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExecutionUser'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExecutionUser'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -Path -Name\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset ExecutionUser\" {\n\t\t<#\n\t\tExecutionUser -\n\t\tExecutionUser -Name -ExecutionUsername\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365RsatSoapHostname.Tests.ps1",
    "content": "﻿Describe \"Get-D365RsatSoapHostname Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365RsatSoapHostname).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365Runbook.Tests.ps1",
    "content": "﻿Describe \"Get-D365Runbook Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365Runbook).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Get-D365Runbook).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365Runbook).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Latest' {\n\t\t\t$parameter = (Get-Command Get-D365Runbook).Parameters['Latest']\n\t\t\t$parameter.Name | Should -Be 'Latest'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Path -Name -Latest\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365RunbookId.Tests.ps1",
    "content": "﻿Describe \"Get-D365RunbookId Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365RunbookId).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Get-D365RunbookId).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path\n\t\t__AllParameterSets -Path\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365RunbookLogFile.Tests.ps1",
    "content": "﻿Describe \"Get-D365RunbookLogFile Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365RunbookLogFile).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Get-D365RunbookLogFile).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Step' {\n\t\t\t$parameter = (Get-Command Get-D365RunbookLogFile).Parameters['Step']\n\t\t\t$parameter.Name | Should -Be 'Step'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Latest' {\n\t\t\t$parameter = (Get-Command Get-D365RunbookLogFile).Parameters['Latest']\n\t\t\t$parameter.Name | Should -Be 'Latest'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OpenInEditor' {\n\t\t\t$parameter = (Get-Command Get-D365RunbookLogFile).Parameters['OpenInEditor']\n\t\t\t$parameter.Name | Should -Be 'OpenInEditor'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path -Step\n\t\t__AllParameterSets -Path -Step -Latest -OpenInEditor\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365SDPCleanUp.Tests.ps1",
    "content": "﻿Describe \"Get-D365SDPCleanUp Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365SDPCleanUp).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365SDPDetails.Tests.ps1",
    "content": "﻿Describe \"Get-D365SDPDetails Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365SDPDetails).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Get-D365SDPDetails).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path\n\t\t__AllParameterSets -Path\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365Table.Tests.ps1",
    "content": "﻿Describe \"Get-D365Table Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365Table).ParameterSets.Name | Should -Be 'Default', 'TableId'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365Table).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Id' {\n\t\t\t$parameter = (Get-Command Get-D365Table).Parameters['Id']\n\t\t\t$parameter.Name | Should -Be 'Id'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'TableId'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'TableId'\n\t\t\t$parameter.ParameterSets['TableId'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['TableId'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['TableId'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableId'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableId'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Get-D365Table).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Get-D365Table).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Get-D365Table).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Get-D365Table).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -Name -DatabaseServer -DatabaseName -SqlUser -SqlPwd\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset TableId\" {\n\t\t<#\n\t\tTableId -Id\n\t\tTableId -Id -DatabaseServer -DatabaseName -SqlUser -SqlPwd\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365TableField.Tests.ps1",
    "content": "﻿Describe \"Get-D365TableField Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365TableField).ParameterSets.Name | Should -Be 'Default', 'SearchByNameForce', 'TableName'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter TableId' {\n\t\t\t$parameter = (Get-Command Get-D365TableField).Parameters['TableId']\n\t\t\t$parameter.Name | Should -Be 'TableId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365TableField).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'SearchByNameForce', 'TableName', 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'SearchByNameForce'\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'TableName'\n\t\t\t$parameter.ParameterSets['TableName'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FieldId' {\n\t\t\t$parameter = (Get-Command Get-D365TableField).Parameters['FieldId']\n\t\t\t$parameter.Name | Should -Be 'FieldId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'TableName', 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'TableName'\n\t\t\t$parameter.ParameterSets['TableName'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Get-D365TableField).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'SearchByNameForce', 'TableName', 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'SearchByNameForce'\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'TableName'\n\t\t\t$parameter.ParameterSets['TableName'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Get-D365TableField).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'SearchByNameForce', 'TableName', 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'SearchByNameForce'\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'TableName'\n\t\t\t$parameter.ParameterSets['TableName'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Get-D365TableField).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'SearchByNameForce', 'TableName', 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'SearchByNameForce'\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'TableName'\n\t\t\t$parameter.ParameterSets['TableName'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Get-D365TableField).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'SearchByNameForce', 'TableName', 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'SearchByNameForce'\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'TableName'\n\t\t\t$parameter.ParameterSets['TableName'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter TableName' {\n\t\t\t$parameter = (Get-Command Get-D365TableField).Parameters['TableName']\n\t\t\t$parameter.Name | Should -Be 'TableName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'TableName'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'TableName'\n\t\t\t$parameter.ParameterSets['TableName'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['TableName'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter IncludeTableDetails' {\n\t\t\t$parameter = (Get-Command Get-D365TableField).Parameters['IncludeTableDetails']\n\t\t\t$parameter.Name | Should -Be 'IncludeTableDetails'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'TableName', 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'TableName'\n\t\t\t$parameter.ParameterSets['TableName'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['TableName'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SearchAcrossTables' {\n\t\t\t$parameter = (Get-Command Get-D365TableField).Parameters['SearchAcrossTables']\n\t\t\t$parameter.Name | Should -Be 'SearchAcrossTables'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'SearchByNameForce'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'SearchByNameForce'\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['SearchByNameForce'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -TableId\n\t\tDefault -TableId -Name -FieldId -DatabaseServer -DatabaseName -SqlUser -SqlPwd -IncludeTableDetails\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset SearchByNameForce\" {\n\t\t<#\n\t\tSearchByNameForce -SearchAcrossTables\n\t\tSearchByNameForce -Name -DatabaseServer -DatabaseName -SqlUser -SqlPwd -SearchAcrossTables\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset TableName\" {\n\t\t<#\n\t\tTableName -TableName\n\t\tTableName -Name -FieldId -DatabaseServer -DatabaseName -SqlUser -SqlPwd -TableName -IncludeTableDetails\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365TableSequence.Tests.ps1",
    "content": "﻿Describe \"Get-D365TableSequence Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365TableSequence).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter TableName' {\n\t\t\t$parameter = (Get-Command Get-D365TableSequence).Parameters['TableName']\n\t\t\t$parameter.Name | Should -Be 'TableName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Get-D365TableSequence).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Get-D365TableSequence).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Get-D365TableSequence).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Get-D365TableSequence).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -TableName -DatabaseServer -DatabaseName -SqlUser -SqlPwd\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365TablesInChangedTracking.Tests.ps1",
    "content": "﻿Describe \"Get-D365TablesInChangedTracking Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365TablesInChangedTracking).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Get-D365TablesInChangedTracking).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Get-D365TablesInChangedTracking).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Get-D365TablesInChangedTracking).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Get-D365TablesInChangedTracking).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Get-D365TablesInChangedTracking).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Name -DatabaseServer -DatabaseName -SqlUser -SqlPwd\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365TfsUri.Tests.ps1",
    "content": "﻿Describe \"Get-D365TfsUri Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365TfsUri).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Get-D365TfsUri).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -Path\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365TfsWorkspace.Tests.ps1",
    "content": "﻿Describe \"Get-D365TfsWorkspace Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365TfsWorkspace).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Get-D365TfsWorkspace).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter TfsUri' {\n\t\t\t$parameter = (Get-Command Get-D365TfsWorkspace).Parameters['TfsUri']\n\t\t\t$parameter.Name | Should -Be 'TfsUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Path -TfsUri\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365Url.Tests.ps1",
    "content": "﻿Describe \"Get-D365Url Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365Url).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Get-D365Url).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Force\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365User.Tests.ps1",
    "content": "﻿Describe \"Get-D365User Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365User).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Get-D365User).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Get-D365User).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Get-D365User).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Get-D365User).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Email' {\n\t\t\t$parameter = (Get-Command Get-D365User).Parameters['Email']\n\t\t\t$parameter.Name | Should -Be 'Email'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ExcludeSystemUsers' {\n\t\t\t$parameter = (Get-Command Get-D365User).Parameters['ExcludeSystemUsers']\n\t\t\t$parameter.Name | Should -Be 'ExcludeSystemUsers'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -Email -ExcludeSystemUsers\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365UserAuthenticationDetail.Tests.ps1",
    "content": "﻿Describe \"Get-D365UserAuthenticationDetail Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365UserAuthenticationDetail).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Email' {\n\t\t\t$parameter = (Get-Command Get-D365UserAuthenticationDetail).Parameters['Email']\n\t\t\t$parameter.Name | Should -Be 'Email'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Email\n\t\t__AllParameterSets -Email\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365VisualStudioCompilerResult.Tests.ps1",
    "content": "﻿Describe \"Get-D365VisualStudioCompilerResult Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365VisualStudioCompilerResult).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Module' {\n\t\t\t$parameter = (Get-Command Get-D365VisualStudioCompilerResult).Parameters['Module']\n\t\t\t$parameter.Name | Should -Be 'Module'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ErrorsOnly' {\n\t\t\t$parameter = (Get-Command Get-D365VisualStudioCompilerResult).Parameters['ErrorsOnly']\n\t\t\t$parameter.Name | Should -Be 'ErrorsOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputTotals' {\n\t\t\t$parameter = (Get-Command Get-D365VisualStudioCompilerResult).Parameters['OutputTotals']\n\t\t\t$parameter.Name | Should -Be 'OutputTotals'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputAsObjects' {\n\t\t\t$parameter = (Get-Command Get-D365VisualStudioCompilerResult).Parameters['OutputAsObjects']\n\t\t\t$parameter.Name | Should -Be 'OutputAsObjects'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Get-D365VisualStudioCompilerResult).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Module -ErrorsOnly -OutputTotals -OutputAsObjects -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365WebServerType.Tests.ps1",
    "content": "﻿Describe \"Get-D365WebServerType Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365WebServerType).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Get-D365WindowsActivationStatus.Tests.ps1",
    "content": "﻿Describe \"Get-D365WindowsActivationStatus Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Get-D365WindowsActivationStatus).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Import-D365AadApplication.Tests.ps1",
    "content": "﻿Describe \"Import-D365AadApplication Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Import-D365AadApplication).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Import-D365AadApplication).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter UserId' {\n\t\t\t$parameter = (Get-Command Import-D365AadApplication).Parameters['UserId']\n\t\t\t$parameter.Name | Should -Be 'UserId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ClientId' {\n\t\t\t$parameter = (Get-Command Import-D365AadApplication).Parameters['ClientId']\n\t\t\t$parameter.Name | Should -Be 'ClientId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Import-D365AadApplication).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Import-D365AadApplication).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Import-D365AadApplication).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Import-D365AadApplication).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Name -UserId -ClientId\n\t\t__AllParameterSets -Name -UserId -ClientId -DatabaseServer -DatabaseName -SqlUser -SqlPwd\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Import-D365AadUser.Tests.ps1",
    "content": "﻿Describe \"Import-D365AadUser Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Import-D365AadUser).ParameterSets.Name | Should -Be 'UserListImport', 'GroupNameImport', 'GroupIdImport'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter AadGroupName' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['AadGroupName']\n\t\t\t$parameter.Name | Should -Be 'AadGroupName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'GroupNameImport'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'GroupNameImport'\n\t\t\t$parameter.ParameterSets['GroupNameImport'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['GroupNameImport'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['GroupNameImport'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['GroupNameImport'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['GroupNameImport'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Users' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['Users']\n\t\t\t$parameter.Name | Should -Be 'Users'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'UserListImport'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'UserListImport'\n\t\t\t$parameter.ParameterSets['UserListImport'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['UserListImport'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['UserListImport'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['UserListImport'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['UserListImport'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter StartupCompany' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['StartupCompany']\n\t\t\t$parameter.Name | Should -Be 'StartupCompany'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter IdPrefix' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['IdPrefix']\n\t\t\t$parameter.Name | Should -Be 'IdPrefix'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter NameSuffix' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['NameSuffix']\n\t\t\t$parameter.Name | Should -Be 'NameSuffix'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter IdValue' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['IdValue']\n\t\t\t$parameter.Name | Should -Be 'IdValue'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 9\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter NameValue' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['NameValue']\n\t\t\t$parameter.Name | Should -Be 'NameValue'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 10\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AzureAdCredential' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['AzureAdCredential']\n\t\t\t$parameter.Name | Should -Be 'AzureAdCredential'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.PSCredential\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 11\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SkipAzureAd' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['SkipAzureAd']\n\t\t\t$parameter.Name | Should -Be 'SkipAzureAd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'UserListImport'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'UserListImport'\n\t\t\t$parameter.ParameterSets['UserListImport'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['UserListImport'].Position | Should -Be 12\n\t\t\t$parameter.ParameterSets['UserListImport'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['UserListImport'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['UserListImport'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ForceExactAadGroupName' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['ForceExactAadGroupName']\n\t\t\t$parameter.Name | Should -Be 'ForceExactAadGroupName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'GroupNameImport'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'GroupNameImport'\n\t\t\t$parameter.ParameterSets['GroupNameImport'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['GroupNameImport'].Position | Should -Be 13\n\t\t\t$parameter.ParameterSets['GroupNameImport'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['GroupNameImport'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['GroupNameImport'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AadGroupId' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['AadGroupId']\n\t\t\t$parameter.Name | Should -Be 'AadGroupId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'GroupIdImport'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'GroupIdImport'\n\t\t\t$parameter.ParameterSets['GroupIdImport'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['GroupIdImport'].Position | Should -Be 14\n\t\t\t$parameter.ParameterSets['GroupIdImport'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['GroupIdImport'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['GroupIdImport'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EmailValue' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['EmailValue']\n\t\t\t$parameter.Name | Should -Be 'EmailValue'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 15\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter TenantId' {\n\t\t\t$parameter = (Get-Command Import-D365AadUser).Parameters['TenantId']\n\t\t\t$parameter.Name | Should -Be 'TenantId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 16\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset UserListImport\" {\n\t\t<#\n\t\tUserListImport -Users\n\t\tUserListImport -Users -StartupCompany -DatabaseServer -DatabaseName -SqlUser -SqlPwd -IdPrefix -NameSuffix -IdValue -NameValue -AzureAdCredential -SkipAzureAd -EmailValue -TenantId\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset GroupNameImport\" {\n\t\t<#\n\t\tGroupNameImport -AadGroupName\n\t\tGroupNameImport -AadGroupName -StartupCompany -DatabaseServer -DatabaseName -SqlUser -SqlPwd -IdPrefix -NameSuffix -IdValue -NameValue -AzureAdCredential -ForceExactAadGroupName -EmailValue -TenantId\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset GroupIdImport\" {\n\t\t<#\n\t\tGroupIdImport -AadGroupId\n\t\tGroupIdImport -StartupCompany -DatabaseServer -DatabaseName -SqlUser -SqlPwd -IdPrefix -NameSuffix -IdValue -NameValue -AzureAdCredential -AadGroupId -EmailValue -TenantId\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Import-D365Bacpac.Tests.ps1",
    "content": "﻿Describe \"Import-D365Bacpac Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Import-D365Bacpac).ParameterSets.Name | Should -Be 'ImportTier1', 'ImportOnlyTier2', 'ImportTier2'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ImportModeTier1' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['ImportModeTier1']\n\t\t\t$parameter.Name | Should -Be 'ImportModeTier1'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ImportTier1'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportTier1'\n\t\t\t$parameter.ParameterSets['ImportTier1'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier1'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['ImportTier1'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier1'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier1'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ImportModeTier2' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['ImportModeTier2']\n\t\t\t$parameter.Name | Should -Be 'ImportModeTier2'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier2'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2'\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportTier2'\n\t\t\t$parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier1', 'ImportTier2', '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2'\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportTier1'\n\t\t\t$parameter.ParameterSets['ImportTier1'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier1'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['ImportTier1'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier1'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier1'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportTier2'\n\t\t\t$parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier1', 'ImportTier2', '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2'\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportTier1'\n\t\t\t$parameter.ParameterSets['ImportTier1'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier1'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['ImportTier1'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier1'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier1'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportTier2'\n\t\t\t$parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BacpacFile' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['BacpacFile']\n\t\t\t$parameter.Name | Should -Be 'BacpacFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter NewDatabaseName' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['NewDatabaseName']\n\t\t\t$parameter.Name | Should -Be 'NewDatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AxDeployExtUserPwd' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['AxDeployExtUserPwd']\n\t\t\t$parameter.Name | Should -Be 'AxDeployExtUserPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier2'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2'\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportTier2'\n\t\t\t$parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AxDbAdminPwd' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['AxDbAdminPwd']\n\t\t\t$parameter.Name | Should -Be 'AxDbAdminPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier2'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2'\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 8\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportTier2'\n\t\t\t$parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].Position | Should -Be 8\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AxRuntimeUserPwd' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['AxRuntimeUserPwd']\n\t\t\t$parameter.Name | Should -Be 'AxRuntimeUserPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier2'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2'\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 9\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportTier2'\n\t\t\t$parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].Position | Should -Be 9\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AxMrRuntimeUserPwd' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['AxMrRuntimeUserPwd']\n\t\t\t$parameter.Name | Should -Be 'AxMrRuntimeUserPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier2'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2'\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 10\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportTier2'\n\t\t\t$parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].Position | Should -Be 10\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AxRetailRuntimeUserPwd' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['AxRetailRuntimeUserPwd']\n\t\t\t$parameter.Name | Should -Be 'AxRetailRuntimeUserPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier2'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2'\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 11\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportTier2'\n\t\t\t$parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].Position | Should -Be 11\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AxRetailDataSyncUserPwd' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['AxRetailDataSyncUserPwd']\n\t\t\t$parameter.Name | Should -Be 'AxRetailDataSyncUserPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier2'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2'\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 12\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportTier2'\n\t\t\t$parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].Position | Should -Be 12\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AxDbReadonlyUserPwd' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['AxDbReadonlyUserPwd']\n\t\t\t$parameter.Name | Should -Be 'AxDbReadonlyUserPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier2'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2'\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 13\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportTier2'\n\t\t\t$parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].Position | Should -Be 13\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter CustomSqlFile' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['CustomSqlFile']\n\t\t\t$parameter.Name | Should -Be 'CustomSqlFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ModelFile' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['ModelFile']\n\t\t\t$parameter.Name | Should -Be 'ModelFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DiagnosticFile' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['DiagnosticFile']\n\t\t\t$parameter.Name | Should -Be 'DiagnosticFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ImportOnly' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['ImportOnly']\n\t\t\t$parameter.Name | Should -Be 'ImportOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier1'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2'\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportTier1'\n\t\t\t$parameter.ParameterSets['ImportTier1'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier1'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['ImportTier1'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier1'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportTier1'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MaxParallelism' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['MaxParallelism']\n\t\t\t$parameter.Name | Should -Be 'MaxParallelism'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Properties' {\n\t\t\t$parameter = (Get-Command Import-D365Bacpac).Parameters['Properties']\n\t\t\t$parameter.Name | Should -Be 'Properties'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset ImportTier1\" {\n\t\t<#\n\t\tImportTier1 -ImportModeTier1 -BacpacFile -NewDatabaseName\n\t\tImportTier1 -ImportModeTier1 -DatabaseServer -DatabaseName -SqlUser -SqlPwd -BacpacFile -NewDatabaseName -CustomSqlFile -ModelFile -DiagnosticFile -ImportOnly -MaxParallelism -LogPath -ShowOriginalProgress -OutputCommandOnly -EnableException -Properties\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset ImportOnlyTier2\" {\n\t\t<#\n\t\tImportOnlyTier2 -ImportModeTier2 -SqlUser -SqlPwd -BacpacFile -NewDatabaseName -ImportOnly\n\t\tImportOnlyTier2 -ImportModeTier2 -DatabaseServer -DatabaseName -SqlUser -SqlPwd -BacpacFile -NewDatabaseName -AxDeployExtUserPwd -AxDbAdminPwd -AxRuntimeUserPwd -AxMrRuntimeUserPwd -AxRetailRuntimeUserPwd -AxRetailDataSyncUserPwd -AxDbReadonlyUserPwd -CustomSqlFile -ModelFile -DiagnosticFile -ImportOnly -MaxParallelism -LogPath -ShowOriginalProgress -OutputCommandOnly -EnableException -Properties\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset ImportTier2\" {\n\t\t<#\n\t\tImportTier2 -ImportModeTier2 -SqlUser -SqlPwd -BacpacFile -NewDatabaseName -AxDeployExtUserPwd -AxDbAdminPwd -AxRuntimeUserPwd -AxMrRuntimeUserPwd -AxRetailRuntimeUserPwd -AxRetailDataSyncUserPwd -AxDbReadonlyUserPwd\n\t\tImportTier2 -ImportModeTier2 -DatabaseServer -DatabaseName -SqlUser -SqlPwd -BacpacFile -NewDatabaseName -AxDeployExtUserPwd -AxDbAdminPwd -AxRuntimeUserPwd -AxMrRuntimeUserPwd -AxRetailRuntimeUserPwd -AxRetailDataSyncUserPwd -AxDbReadonlyUserPwd -CustomSqlFile -ModelFile -DiagnosticFile -MaxParallelism -LogPath -ShowOriginalProgress -OutputCommandOnly -EnableException -Properties\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Import-D365Dacpac.Tests.ps1",
    "content": "﻿Describe \"Import-D365Dacpac Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Import-D365Dacpac).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Import-D365Dacpac).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ModelFile' {\n\t\t\t$parameter = (Get-Command Import-D365Dacpac).Parameters['ModelFile']\n\t\t\t$parameter.Name | Should -Be 'ModelFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PublishFile' {\n\t\t\t$parameter = (Get-Command Import-D365Dacpac).Parameters['PublishFile']\n\t\t\t$parameter.Name | Should -Be 'PublishFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DiagnosticFile' {\n\t\t\t$parameter = (Get-Command Import-D365Dacpac).Parameters['DiagnosticFile']\n\t\t\t$parameter.Name | Should -Be 'DiagnosticFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MaxParallelism' {\n\t\t\t$parameter = (Get-Command Import-D365Dacpac).Parameters['MaxParallelism']\n\t\t\t$parameter.Name | Should -Be 'MaxParallelism'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Import-D365Dacpac).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Import-D365Dacpac).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Import-D365Dacpac).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Import-D365Dacpac).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Import-D365Dacpac).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 9\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Import-D365Dacpac).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Import-D365Dacpac).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Import-D365Dacpac).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path\n\t\t__AllParameterSets -Path -ModelFile -PublishFile -DiagnosticFile -MaxParallelism -DatabaseServer -DatabaseName -SqlUser -SqlPwd -LogPath -ShowOriginalProgress -OutputCommandOnly -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Import-D365ExternalUser.Tests.ps1",
    "content": "﻿Describe \"Import-D365ExternalUser Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Import-D365ExternalUser).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Id' {\n\t\t\t$parameter = (Get-Command Import-D365ExternalUser).Parameters['Id']\n\t\t\t$parameter.Name | Should -Be 'Id'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Import-D365ExternalUser).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Email' {\n\t\t\t$parameter = (Get-Command Import-D365ExternalUser).Parameters['Email']\n\t\t\t$parameter.Name | Should -Be 'Email'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Enabled' {\n\t\t\t$parameter = (Get-Command Import-D365ExternalUser).Parameters['Enabled']\n\t\t\t$parameter.Name | Should -Be 'Enabled'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Company' {\n\t\t\t$parameter = (Get-Command Import-D365ExternalUser).Parameters['Company']\n\t\t\t$parameter.Name | Should -Be 'Company'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Language' {\n\t\t\t$parameter = (Get-Command Import-D365ExternalUser).Parameters['Language']\n\t\t\t$parameter.Name | Should -Be 'Language'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Import-D365ExternalUser).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Import-D365ExternalUser).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Import-D365ExternalUser).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Import-D365ExternalUser).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 9\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Id -Name -Email\n\t\t__AllParameterSets -Id -Name -Email -Enabled -Company -Language -DatabaseServer -DatabaseName -SqlUser -SqlPwd\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Import-D365Model.Tests.ps1",
    "content": "﻿Describe \"Import-D365Model Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Import-D365Model).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Import-D365Model).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Import-D365Model).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command Import-D365Model).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Replace' {\n\t\t\t$parameter = (Get-Command Import-D365Model).Parameters['Replace']\n\t\t\t$parameter.Name | Should -Be 'Replace'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Import-D365Model).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Import-D365Model).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Import-D365Model).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path\n\t\t__AllParameterSets -Path -BinDir -MetaDataDir -Replace -LogPath -ShowOriginalProgress -OutputCommandOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Import-D365RsatSelfServiceCertificates.Tests.ps1",
    "content": "﻿Describe \"Import-D365RsatSelfServiceCertificates Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Import-D365RsatSelfServiceCertificates).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Import-D365RsatSelfServiceCertificates).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Password' {\n\t\t\t$parameter = (Get-Command Import-D365RsatSelfServiceCertificates).Parameters['Password']\n\t\t\t$parameter.Name | Should -Be 'Password'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path -Password\n\t\t__AllParameterSets -Path -Password\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Initialize-D365RsatCertificate.Tests.ps1",
    "content": "﻿Describe \"Initialize-D365RsatCertificate Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Initialize-D365RsatCertificate).ParameterSets.Name | Should -Be 'KeepCertificateFile'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter CertificateFileName' {\n\t\t\t$parameter = (Get-Command Initialize-D365RsatCertificate).Parameters['CertificateFileName']\n\t\t\t$parameter.Name | Should -Be 'CertificateFileName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PrivateKeyFileName' {\n\t\t\t$parameter = (Get-Command Initialize-D365RsatCertificate).Parameters['PrivateKeyFileName']\n\t\t\t$parameter.Name | Should -Be 'PrivateKeyFileName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Password' {\n\t\t\t$parameter = (Get-Command Initialize-D365RsatCertificate).Parameters['Password']\n\t\t\t$parameter.Name | Should -Be 'Password'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Security.SecureString\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter CertificateOnly' {\n\t\t\t$parameter = (Get-Command Initialize-D365RsatCertificate).Parameters['CertificateOnly']\n\t\t\t$parameter.Name | Should -Be 'CertificateOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter KeepCertificateFile' {\n\t\t\t$parameter = (Get-Command Initialize-D365RsatCertificate).Parameters['KeepCertificateFile']\n\t\t\t$parameter.Name | Should -Be 'KeepCertificateFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'KeepCertificateFile'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'KeepCertificateFile'\n\t\t\t$parameter.ParameterSets['KeepCertificateFile'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['KeepCertificateFile'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['KeepCertificateFile'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['KeepCertificateFile'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['KeepCertificateFile'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Initialize-D365RsatCertificate).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'KeepCertificateFile'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'KeepCertificateFile'\n\t\t\t$parameter.ParameterSets['KeepCertificateFile'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['KeepCertificateFile'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['KeepCertificateFile'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['KeepCertificateFile'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['KeepCertificateFile'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset KeepCertificateFile\" {\n\t\t<#\n\t\tKeepCertificateFile -\n\t\tKeepCertificateFile -CertificateFileName -PrivateKeyFileName -Password -CertificateOnly -KeepCertificateFile -OutputPath\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Install-D365SupportingSoftware.Tests.ps1",
    "content": "﻿Describe \"Install-D365SupportingSoftware Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Install-D365SupportingSoftware).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Install-D365SupportingSoftware).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Install-D365SupportingSoftware).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Name\n\t\t__AllParameterSets -Name -Force\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365AzCopyTransfer.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365AzCopyTransfer Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365AzCopyTransfer).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter SourceUri' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['SourceUri']\n\t\t\t$parameter.Name | Should -Be 'SourceUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DestinationUri' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['DestinationUri']\n\t\t\t$parameter.Name | Should -Be 'DestinationUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FileName' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['FileName']\n\t\t\t$parameter.Name | Should -Be 'FileName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DeleteOnTransferComplete' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['DeleteOnTransferComplete']\n\t\t\t$parameter.Name | Should -Be 'DeleteOnTransferComplete'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -SourceUri -DestinationUri\n\t\t__AllParameterSets -SourceUri -DestinationUri -FileName -DeleteOnTransferComplete -LogPath -ShowOriginalProgress -OutputCommandOnly -Force -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365AzureDevOpsNugetPush.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365AzureDevOpsNugetPush Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365AzureDevOpsNugetPush).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureDevOpsNugetPush).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Source' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureDevOpsNugetPush).Parameters['Source']\n\t\t\t$parameter.Name | Should -Be 'Source'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureDevOpsNugetPush).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureDevOpsNugetPush).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureDevOpsNugetPush).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureDevOpsNugetPush).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Path -Source -LogPath -ShowOriginalProgress -OutputCommandOnly -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365AzureStorageDownload.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365AzureStorageDownload Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365AzureStorageDownload).ParameterSets.Name | Should -Be 'Default', 'Latest'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter AccountId' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['AccountId']\n\t\t\t$parameter.Name | Should -Be 'AccountId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AccessToken' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['AccessToken']\n\t\t\t$parameter.Name | Should -Be 'AccessToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SAS' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['SAS']\n\t\t\t$parameter.Name | Should -Be 'SAS'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Container' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['Container']\n\t\t\t$parameter.Name | Should -Be 'Container'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FileName' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['FileName']\n\t\t\t$parameter.Name | Should -Be 'FileName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Latest' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['Latest']\n\t\t\t$parameter.Name | Should -Be 'Latest'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Latest'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Latest'\n\t\t\t$parameter.ParameterSets['Latest'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Latest'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['Latest'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Latest'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Latest'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -FileName\n\t\tDefault -AccountId -AccessToken -SAS -Container -FileName -Path -Force -EnableException\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Latest\" {\n\t\t<#\n\t\tLatest -Latest\n\t\tLatest -AccountId -AccessToken -SAS -Container -Path -Latest -Force -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365AzureStorageUpload.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365AzureStorageUpload Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365AzureStorageUpload).ParameterSets.Name | Should -Be 'Default', 'Pipeline'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter AccountId' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['AccountId']\n\t\t\t$parameter.Name | Should -Be 'AccountId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AccessToken' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['AccessToken']\n\t\t\t$parameter.Name | Should -Be 'AccessToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SAS' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['SAS']\n\t\t\t$parameter.Name | Should -Be 'SAS'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Container' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['Container']\n\t\t\t$parameter.Name | Should -Be 'Container'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Filepath' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['Filepath']\n\t\t\t$parameter.Name | Should -Be 'Filepath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Pipeline', 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Pipeline'\n\t\t\t$parameter.ParameterSets['Pipeline'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Pipeline'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Pipeline'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Pipeline'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Pipeline'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ContentType' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['ContentType']\n\t\t\t$parameter.Name | Should -Be 'ContentType'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DeleteOnUpload' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['DeleteOnUpload']\n\t\t\t$parameter.Name | Should -Be 'DeleteOnUpload'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -Filepath\n\t\tDefault -AccountId -AccessToken -SAS -Container -Filepath -ContentType -Force -DeleteOnUpload -EnableException\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Pipeline\" {\n\t\t<#\n\t\tPipeline -Filepath\n\t\tPipeline -AccountId -AccessToken -SAS -Container -Filepath -ContentType -Force -DeleteOnUpload -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365BestPractice.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365BestPractice Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365BestPractice).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Module' {\n\t\t\t$parameter = (Get-Command Invoke-D365BestPractice).Parameters['Module']\n\t\t\t$parameter.Name | Should -Be 'Module'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Model' {\n\t\t\t$parameter = (Get-Command Invoke-D365BestPractice).Parameters['Model']\n\t\t\t$parameter.Name | Should -Be 'Model'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365BestPractice).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365BestPractice).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackagesRoot' {\n\t\t\t$parameter = (Get-Command Invoke-D365BestPractice).Parameters['PackagesRoot']\n\t\t\t$parameter.Name | Should -Be 'PackagesRoot'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365BestPractice).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Invoke-D365BestPractice).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RunFixers' {\n\t\t\t$parameter = (Get-Command Invoke-D365BestPractice).Parameters['RunFixers']\n\t\t\t$parameter.Name | Should -Be 'RunFixers'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Invoke-D365BestPractice).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Module -Model\n\t\t__AllParameterSets -Module -Model -BinDir -MetaDataDir -PackagesRoot -LogPath -ShowOriginalProgress -RunFixers -OutputCommandOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365CompilerResultAnalyzer.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365CompilerResultAnalyzer Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365CompilerResultAnalyzer).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Invoke-D365CompilerResultAnalyzer).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365CompilerResultAnalyzer).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SkipWarnings' {\n\t\t\t$parameter = (Get-Command Invoke-D365CompilerResultAnalyzer).Parameters['SkipWarnings']\n\t\t\t$parameter.Name | Should -Be 'SkipWarnings'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SkipTasks' {\n\t\t\t$parameter = (Get-Command Invoke-D365CompilerResultAnalyzer).Parameters['SkipTasks']\n\t\t\t$parameter.Name | Should -Be 'SkipTasks'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Invoke-D365CompilerResultAnalyzer).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path\n\t\t__AllParameterSets -Path -OutputPath -SkipWarnings -SkipTasks -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365DBSync.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365DbSync Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365DbSync).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter BinDirTools' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSync).Parameters['BinDirTools']\n\t\t\t$parameter.Name | Should -Be 'BinDirTools'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetadataDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSync).Parameters['MetadataDir']\n\t\t\t$parameter.Name | Should -Be 'MetadataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SyncMode' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSync).Parameters['SyncMode']\n\t\t\t$parameter.Name | Should -Be 'SyncMode'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Verbosity' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSync).Parameters['Verbosity']\n\t\t\t$parameter.Name | Should -Be 'Verbosity'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSync).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSync).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSync).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSync).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSync).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSync).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSync).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -BinDirTools -MetadataDir -SyncMode -Verbosity -DatabaseServer -DatabaseName -SqlUser -SqlPwd -LogPath -ShowOriginalProgress -OutputCommandOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365DBSyncPartial.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365DbSyncPartial Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365DbSyncPartial).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter SyncList' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['SyncList']\n\t\t\t$parameter.Name | Should -Be 'SyncList'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SyncExtensionsList' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['SyncExtensionsList']\n\t\t\t$parameter.Name | Should -Be 'SyncExtensionsList'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SyncMode' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['SyncMode']\n\t\t\t$parameter.Name | Should -Be 'SyncMode'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Verbosity' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['Verbosity']\n\t\t\t$parameter.Name | Should -Be 'Verbosity'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDirTools' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['BinDirTools']\n\t\t\t$parameter.Name | Should -Be 'BinDirTools'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetadataDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['MetadataDir']\n\t\t\t$parameter.Name | Should -Be 'MetadataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 9\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 10\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -SyncList -SyncExtensionsList -SyncMode -Verbosity -BinDirTools -MetadataDir -DatabaseServer -DatabaseName -SqlUser -SqlPwd -LogPath -ShowOriginalProgress -OutputCommandOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365DataFlush.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365DataFlush Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365DataFlush).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Url' {\n\t\t\t$parameter = (Get-Command Invoke-D365DataFlush).Parameters['Url']\n\t\t\t$parameter.Name | Should -Be 'Url'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Class' {\n\t\t\t$parameter = (Get-Command Invoke-D365DataFlush).Parameters['Class']\n\t\t\t$parameter.Name | Should -Be 'Class'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Url -Class\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365DbSyncModule.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365DbSyncModule Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365DbSyncModule).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Module' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['Module']\n\t\t\t$parameter.Name | Should -Be 'Module'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Verbosity' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['Verbosity']\n\t\t\t$parameter.Name | Should -Be 'Verbosity'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDirTools' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['BinDirTools']\n\t\t\t$parameter.Name | Should -Be 'BinDirTools'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetadataDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['MetadataDir']\n\t\t\t$parameter.Name | Should -Be 'MetadataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Module\n\t\t__AllParameterSets -Module -Verbosity -BinDirTools -MetadataDir -DatabaseServer -DatabaseName -SqlUser -SqlPwd -LogPath -ShowOriginalProgress -OutputCommandOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365GenerateReportAggregateDataEntity.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365GenerateReportAggregateDataEntity Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365GenerateReportAggregateDataEntity).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportAggregateDataEntity).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportAggregateDataEntity).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportAggregateDataEntity).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -BinDir -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365GenerateReportAggregateMeasure.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365GenerateReportAggregateMeasure Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365GenerateReportAggregateMeasure).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportAggregateMeasure).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportAggregateMeasure).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportAggregateMeasure).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -BinDir -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365GenerateReportConfigKey.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365GenerateReportConfigKey Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365GenerateReportConfigKey).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportConfigKey).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportConfigKey).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportConfigKey).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -BinDir -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365GenerateReportConfigKeyGroup.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365GenerateReportConfigKeyGroup Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365GenerateReportConfigKeyGroup).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportConfigKeyGroup).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportConfigKeyGroup).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportConfigKeyGroup).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -BinDir -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365GenerateReportDataEntity.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365GenerateReportDataEntity Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365GenerateReportDataEntity).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportDataEntity).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportDataEntity).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportDataEntity).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -BinDir -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365GenerateReportDataEntityField.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365GenerateReportDataEntityField Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365GenerateReportDataEntityField).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportDataEntityField).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportDataEntityField).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportDataEntityField).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -BinDir -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365GenerateReportKpi.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365GenerateReportKpi Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365GenerateReportKpi).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportKpi).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportKpi).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportKpi).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -BinDir -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365GenerateReportLicenseCode.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365GenerateReportLicenseCode Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365GenerateReportLicenseCode).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportLicenseCode).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportLicenseCode).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportLicenseCode).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -BinDir -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365GenerateReportMenuItem.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365GenerateReportMenuItem Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365GenerateReportMenuItem).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportMenuItem).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportMenuItem).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportMenuItem).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -BinDir -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365GenerateReportSsrs.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365GenerateReportSsrs Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365GenerateReportSsrs).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportSsrs).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportSsrs).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportSsrs).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -BinDir -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365GenerateReportTable.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365GenerateReportTable Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365GenerateReportTable).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportTable).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportTable).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportTable).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -BinDir -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365GenerateReportWorkflowType.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365GenerateReportWorkflowType Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365GenerateReportWorkflowType).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportWorkflowType).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportWorkflowType).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReportWorkflowType).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -BinDir -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365GenerateReports.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365GenerateReports Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365GenerateReports).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReports).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReports).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Invoke-D365GenerateReports).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -OutputPath -BinDir -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365InstallAzCopy.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365InstallAzCopy Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365InstallAzCopy).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Url' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallAzCopy).Parameters['Url']\n\t\t\t$parameter.Name | Should -Be 'Url'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallAzCopy).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Url -Path\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365InstallLicense.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365InstallLicense Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365InstallLicense).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallLicense).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallLicense).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallLicense).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallLicense).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallLicense).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallLicense).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallLicense).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallLicense).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallLicense).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallLicense).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path\n\t\t__AllParameterSets -Path -DatabaseServer -DatabaseName -SqlUser -SqlPwd -MetaDataDir -BinDir -LogPath -ShowOriginalProgress -OutputCommandOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365InstallNuget.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365InstallNuget Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365InstallNuget).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallNuget).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Url' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallNuget).Parameters['Url']\n\t\t\t$parameter.Name | Should -Be 'Url'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Path -Url\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365InstallSqlPackage.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365InstallSqlPackage Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365InstallSqlPackage).ParameterSets.Name | Should -Be 'ImportUrl', 'ImportLatest'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallSqlPackage).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ImportLatest', 'ImportUrl'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportLatest'\n\t\t\t$parameter.ParameterSets['ImportLatest'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportLatest'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['ImportLatest'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportLatest'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportLatest'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportUrl'\n\t\t\t$parameter.ParameterSets['ImportUrl'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportUrl'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['ImportUrl'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportUrl'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportUrl'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Latest' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallSqlPackage).Parameters['Latest']\n\t\t\t$parameter.Name | Should -Be 'Latest'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ImportLatest'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportLatest'\n\t\t\t$parameter.ParameterSets['ImportLatest'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportLatest'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['ImportLatest'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportLatest'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportLatest'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Url' {\n\t\t\t$parameter = (Get-Command Invoke-D365InstallSqlPackage).Parameters['Url']\n\t\t\t$parameter.Name | Should -Be 'Url'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ImportUrl'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ImportUrl'\n\t\t\t$parameter.ParameterSets['ImportUrl'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportUrl'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['ImportUrl'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportUrl'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ImportUrl'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset ImportUrl\" {\n\t\t<#\n\t\tImportUrl -\n\t\tImportUrl -Path -Url\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset ImportLatest\" {\n\t\t<#\n\t\tImportLatest -\n\t\tImportLatest -Path -Latest\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365LcsApiRefreshToken.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365LcsApiRefreshToken Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365LcsApiRefreshToken).ParameterSets.Name | Should -Be 'Object', 'Simple'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ClientId' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsApiRefreshToken).Parameters['ClientId']\n\t\t\t$parameter.Name | Should -Be 'ClientId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Object', 'Simple'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Object'\n\t\t\t$parameter.ParameterSets['Object'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Object'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Object'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Object'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Object'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Simple'\n\t\t\t$parameter.ParameterSets['Simple'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Simple'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Simple'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Simple'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Simple'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RefreshToken' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsApiRefreshToken).Parameters['RefreshToken']\n\t\t\t$parameter.Name | Should -Be 'RefreshToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Simple'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Simple'\n\t\t\t$parameter.ParameterSets['Simple'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Simple'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Simple'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Simple'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Simple'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter InputObject' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsApiRefreshToken).Parameters['InputObject']\n\t\t\t$parameter.Name | Should -Be 'InputObject'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.PSObject\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Object'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Object'\n\t\t\t$parameter.ParameterSets['Object'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Object'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Object'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Object'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Object'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsApiRefreshToken).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Object\" {\n\t\t<#\n\t\tObject -ClientId\n\t\tObject -ClientId -InputObject -EnableException\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Simple\" {\n\t\t<#\n\t\tSimple -ClientId -RefreshToken\n\t\tSimple -ClientId -RefreshToken -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365LcsDatabaseExport.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365LcsDatabaseExport Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365LcsDatabaseExport).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SourceEnvironmentId' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['SourceEnvironmentId']\n\t\t\t$parameter.Name | Should -Be 'SourceEnvironmentId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BackupName' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['BackupName']\n\t\t\t$parameter.Name | Should -Be 'BackupName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SkipInitialStatusFetch' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['SkipInitialStatusFetch']\n\t\t\t$parameter.Name | Should -Be 'SkipInitialStatusFetch'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FailOnErrorMessage' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['FailOnErrorMessage']\n\t\t\t$parameter.Name | Should -Be 'FailOnErrorMessage'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RetryTimeout' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['RetryTimeout']\n\t\t\t$parameter.Name | Should -Be 'RetryTimeout'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.TimeSpan\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -SourceEnvironmentId -BackupName\n\t\t__AllParameterSets -ProjectId -BearerToken -SourceEnvironmentId -BackupName -LcsApiUri -SkipInitialStatusFetch -FailOnErrorMessage -RetryTimeout -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365LcsDatabaseRefresh.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365LcsDatabaseRefresh Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365LcsDatabaseRefresh).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SourceEnvironmentId' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['SourceEnvironmentId']\n\t\t\t$parameter.Name | Should -Be 'SourceEnvironmentId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter TargetEnvironmentId' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['TargetEnvironmentId']\n\t\t\t$parameter.Name | Should -Be 'TargetEnvironmentId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SkipInitialStatusFetch' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['SkipInitialStatusFetch']\n\t\t\t$parameter.Name | Should -Be 'SkipInitialStatusFetch'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FailOnErrorMessage' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['FailOnErrorMessage']\n\t\t\t$parameter.Name | Should -Be 'FailOnErrorMessage'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RetryTimeout' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['RetryTimeout']\n\t\t\t$parameter.Name | Should -Be 'RetryTimeout'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.TimeSpan\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -SourceEnvironmentId -TargetEnvironmentId\n\t\t__AllParameterSets -ProjectId -BearerToken -SourceEnvironmentId -TargetEnvironmentId -LcsApiUri -SkipInitialStatusFetch -FailOnErrorMessage -RetryTimeout -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365LcsDeployment.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365LcsDeployment Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365LcsDeployment).ParameterSets.Name | Should -Be 'VM', 'Self-Service'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AssetId' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['AssetId']\n\t\t\t$parameter.Name | Should -Be 'AssetId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnvironmentId' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['EnvironmentId']\n\t\t\t$parameter.Name | Should -Be 'EnvironmentId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter UpdateName' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['UpdateName']\n\t\t\t$parameter.Name | Should -Be 'UpdateName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Self-Service'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Self-Service'\n\t\t\t$parameter.ParameterSets['Self-Service'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Self-Service'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Self-Service'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Self-Service'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Self-Service'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FailOnErrorMessage' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['FailOnErrorMessage']\n\t\t\t$parameter.Name | Should -Be 'FailOnErrorMessage'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RetryTimeout' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['RetryTimeout']\n\t\t\t$parameter.Name | Should -Be 'RetryTimeout'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.TimeSpan\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset VM\" {\n\t\t<#\n\t\tVM -AssetId -EnvironmentId\n\t\tVM -ProjectId -AssetId -EnvironmentId -BearerToken -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Self-Service\" {\n\t\t<#\n\t\tSelf-Service -AssetId -EnvironmentId -UpdateName\n\t\tSelf-Service -ProjectId -AssetId -EnvironmentId -UpdateName -BearerToken -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365LcsEnvironmentStart.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365LcsEnvironmentStart Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365LcsEnvironmentStart).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsEnvironmentStart).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsEnvironmentStart).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnvironmentId' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsEnvironmentStart).Parameters['EnvironmentId']\n\t\t\t$parameter.Name | Should -Be 'EnvironmentId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsEnvironmentStart).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FailOnErrorMessage' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsEnvironmentStart).Parameters['FailOnErrorMessage']\n\t\t\t$parameter.Name | Should -Be 'FailOnErrorMessage'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RetryTimeout' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsEnvironmentStart).Parameters['RetryTimeout']\n\t\t\t$parameter.Name | Should -Be 'RetryTimeout'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.TimeSpan\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsEnvironmentStart).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -EnvironmentId\n\t\t__AllParameterSets -ProjectId -BearerToken -EnvironmentId -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365LcsEnvironmentStop.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365LcsEnvironmentStop Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365LcsEnvironmentStop).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsEnvironmentStop).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsEnvironmentStop).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnvironmentId' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsEnvironmentStop).Parameters['EnvironmentId']\n\t\t\t$parameter.Name | Should -Be 'EnvironmentId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsEnvironmentStop).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FailOnErrorMessage' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsEnvironmentStop).Parameters['FailOnErrorMessage']\n\t\t\t$parameter.Name | Should -Be 'FailOnErrorMessage'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RetryTimeout' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsEnvironmentStop).Parameters['RetryTimeout']\n\t\t\t$parameter.Name | Should -Be 'RetryTimeout'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.TimeSpan\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsEnvironmentStop).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -EnvironmentId\n\t\t__AllParameterSets -ProjectId -BearerToken -EnvironmentId -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365LcsUpload.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365LcsUpload Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365LcsUpload).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsUpload).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsUpload).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FilePath' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsUpload).Parameters['FilePath']\n\t\t\t$parameter.Name | Should -Be 'FilePath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FileType' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsUpload).Parameters['FileType']\n\t\t\t$parameter.Name | Should -Be 'FileType'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be LcsAssetFileType\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsUpload).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Filename' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsUpload).Parameters['Filename']\n\t\t\t$parameter.Name | Should -Be 'Filename'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FileDescription' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsUpload).Parameters['FileDescription']\n\t\t\t$parameter.Name | Should -Be 'FileDescription'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsUpload).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FailOnErrorMessage' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsUpload).Parameters['FailOnErrorMessage']\n\t\t\t$parameter.Name | Should -Be 'FailOnErrorMessage'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RetryTimeout' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsUpload).Parameters['RetryTimeout']\n\t\t\t$parameter.Name | Should -Be 'RetryTimeout'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.TimeSpan\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Invoke-D365LcsUpload).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -FilePath\n\t\t__AllParameterSets -ProjectId -BearerToken -FilePath -FileType -Name -Filename -FileDescription -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365ModuleCompile.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365ModuleCompile Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365ModuleCompile).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Module' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['Module']\n\t\t\t$parameter.Name | Should -Be 'Module'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['OutputDir']\n\t\t\t$parameter.Name | Should -Be 'OutputDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ReferenceDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['ReferenceDir']\n\t\t\t$parameter.Name | Should -Be 'ReferenceDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter XRefSqlServer' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['XRefSqlServer']\n\t\t\t$parameter.Name | Should -Be 'XRefSqlServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter XRefDbName' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['XRefDbName']\n\t\t\t$parameter.Name | Should -Be 'XRefDbName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter XRefGeneration' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['XRefGeneration']\n\t\t\t$parameter.Name | Should -Be 'XRefGeneration'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter XRefGenerationOnly' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['XRefGenerationOnly']\n\t\t\t$parameter.Name | Should -Be 'XRefGenerationOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Module\n\t\t__AllParameterSets -Module -OutputDir -LogPath -MetaDataDir -ReferenceDir -BinDir -XRefSqlServer -XRefDbName -XRefGeneration -XRefGenerationOnly -ShowOriginalProgress -OutputCommandOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365ModuleFullCompile.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365ModuleFullCompile Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365ModuleFullCompile).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Module' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleFullCompile).Parameters['Module']\n\t\t\t$parameter.Name | Should -Be 'Module'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleFullCompile).Parameters['OutputDir']\n\t\t\t$parameter.Name | Should -Be 'OutputDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleFullCompile).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleFullCompile).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ReferenceDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleFullCompile).Parameters['ReferenceDir']\n\t\t\t$parameter.Name | Should -Be 'ReferenceDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleFullCompile).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleFullCompile).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleFullCompile).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Module\n\t\t__AllParameterSets -Module -OutputDir -LogPath -MetaDataDir -ReferenceDir -BinDir -ShowOriginalProgress -OutputCommandOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365ModuleLabelGeneration.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365ModuleLabelGeneration Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365ModuleLabelGeneration).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Module' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleLabelGeneration).Parameters['Module']\n\t\t\t$parameter.Name | Should -Be 'Module'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleLabelGeneration).Parameters['OutputDir']\n\t\t\t$parameter.Name | Should -Be 'OutputDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleLabelGeneration).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleLabelGeneration).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ReferenceDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleLabelGeneration).Parameters['ReferenceDir']\n\t\t\t$parameter.Name | Should -Be 'ReferenceDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleLabelGeneration).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleLabelGeneration).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleLabelGeneration).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Module\n\t\t__AllParameterSets -Module -OutputDir -LogPath -MetaDataDir -ReferenceDir -BinDir -ShowOriginalProgress -OutputCommandOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365ModuleReportsCompile.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365ModuleReportsCompile Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365ModuleReportsCompile).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Module' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleReportsCompile).Parameters['Module']\n\t\t\t$parameter.Name | Should -Be 'Module'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleReportsCompile).Parameters['OutputDir']\n\t\t\t$parameter.Name | Should -Be 'OutputDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleReportsCompile).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleReportsCompile).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ReferenceDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleReportsCompile).Parameters['ReferenceDir']\n\t\t\t$parameter.Name | Should -Be 'ReferenceDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleReportsCompile).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleReportsCompile).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Invoke-D365ModuleReportsCompile).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Module\n\t\t__AllParameterSets -Module -OutputDir -LogPath -MetaDataDir -ReferenceDir -BinDir -ShowOriginalProgress -OutputCommandOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365ProcessModule.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365ProcessModule Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365ProcessModule).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Module' {\n\t\t\t$parameter = (Get-Command Invoke-D365ProcessModule).Parameters['Module']\n\t\t\t$parameter.Name | Should -Be 'Module'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ExecuteCompile' {\n\t\t\t$parameter = (Get-Command Invoke-D365ProcessModule).Parameters['ExecuteCompile']\n\t\t\t$parameter.Name | Should -Be 'ExecuteCompile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ExecuteSync' {\n\t\t\t$parameter = (Get-Command Invoke-D365ProcessModule).Parameters['ExecuteSync']\n\t\t\t$parameter.Name | Should -Be 'ExecuteSync'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ExecuteDeployReports' {\n\t\t\t$parameter = (Get-Command Invoke-D365ProcessModule).Parameters['ExecuteDeployReports']\n\t\t\t$parameter.Name | Should -Be 'ExecuteDeployReports'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ProcessModule).Parameters['OutputDir']\n\t\t\t$parameter.Name | Should -Be 'OutputDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365ProcessModule).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ProcessModule).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ReferenceDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ProcessModule).Parameters['ReferenceDir']\n\t\t\t$parameter.Name | Should -Be 'ReferenceDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365ProcessModule).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Invoke-D365ProcessModule).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Invoke-D365ProcessModule).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Module\n\t\t__AllParameterSets -Module -ExecuteCompile -ExecuteSync -ExecuteDeployReports -OutputDir -LogPath -MetaDataDir -ReferenceDir -BinDir -ShowOriginalProgress -OutputCommandOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365ReArmWindows.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365ReArmWindows Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365ReArmWindows).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Restart' {\n\t\t\t$parameter = (Get-Command Invoke-D365ReArmWindows).Parameters['Restart']\n\t\t\t$parameter.Name | Should -Be 'Restart'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Restart\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365RunbookAnalyzer.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365RunbookAnalyzer Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365RunbookAnalyzer).ParameterSets.Name | Should -Be 'Default', 'FailedOnlyAsObjects', 'FailedOnly'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Invoke-D365RunbookAnalyzer).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'FailedOnlyAsObjects', 'FailedOnly', 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'FailedOnlyAsObjects'\n\t\t\t$parameter.ParameterSets['FailedOnlyAsObjects'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['FailedOnlyAsObjects'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['FailedOnlyAsObjects'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['FailedOnlyAsObjects'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['FailedOnlyAsObjects'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'FailedOnly'\n\t\t\t$parameter.ParameterSets['FailedOnly'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['FailedOnly'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['FailedOnly'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['FailedOnly'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['FailedOnly'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FailedOnly' {\n\t\t\t$parameter = (Get-Command Invoke-D365RunbookAnalyzer).Parameters['FailedOnly']\n\t\t\t$parameter.Name | Should -Be 'FailedOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'FailedOnly'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'FailedOnly'\n\t\t\t$parameter.ParameterSets['FailedOnly'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['FailedOnly'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['FailedOnly'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['FailedOnly'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['FailedOnly'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FailedOnlyAsObjects' {\n\t\t\t$parameter = (Get-Command Invoke-D365RunbookAnalyzer).Parameters['FailedOnlyAsObjects']\n\t\t\t$parameter.Name | Should -Be 'FailedOnlyAsObjects'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'FailedOnlyAsObjects'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'FailedOnlyAsObjects'\n\t\t\t$parameter.ParameterSets['FailedOnlyAsObjects'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['FailedOnlyAsObjects'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['FailedOnlyAsObjects'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['FailedOnlyAsObjects'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['FailedOnlyAsObjects'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -Path\n\t\tDefault -Path\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset FailedOnlyAsObjects\" {\n\t\t<#\n\t\tFailedOnlyAsObjects -Path\n\t\tFailedOnlyAsObjects -Path -FailedOnlyAsObjects\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset FailedOnly\" {\n\t\t<#\n\t\tFailedOnly -Path\n\t\tFailedOnly -Path -FailedOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365SCDPBundleInstall.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365SCDPBundleInstall Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365SCDPBundleInstall).ParameterSets.Name | Should -Be 'InstallOnly', 'Tfs'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter InstallOnly' {\n\t\t\t$parameter = (Get-Command Invoke-D365SCDPBundleInstall).Parameters['InstallOnly']\n\t\t\t$parameter.Name | Should -Be 'InstallOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'InstallOnly'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'InstallOnly'\n\t\t\t$parameter.ParameterSets['InstallOnly'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['InstallOnly'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['InstallOnly'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['InstallOnly'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['InstallOnly'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Command' {\n\t\t\t$parameter = (Get-Command Invoke-D365SCDPBundleInstall).Parameters['Command']\n\t\t\t$parameter.Name | Should -Be 'Command'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Tfs'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Tfs'\n\t\t\t$parameter.ParameterSets['Tfs'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Tfs'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['Tfs'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Tfs'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Tfs'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Invoke-D365SCDPBundleInstall).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365SCDPBundleInstall).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter TfsWorkspaceDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365SCDPBundleInstall).Parameters['TfsWorkspaceDir']\n\t\t\t$parameter.Name | Should -Be 'TfsWorkspaceDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Tfs'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Tfs'\n\t\t\t$parameter.ParameterSets['Tfs'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Tfs'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['Tfs'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Tfs'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Tfs'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter TfsUri' {\n\t\t\t$parameter = (Get-Command Invoke-D365SCDPBundleInstall).Parameters['TfsUri']\n\t\t\t$parameter.Name | Should -Be 'TfsUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Tfs'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Tfs'\n\t\t\t$parameter.ParameterSets['Tfs'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Tfs'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['Tfs'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Tfs'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Tfs'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowModifiedFiles' {\n\t\t\t$parameter = (Get-Command Invoke-D365SCDPBundleInstall).Parameters['ShowModifiedFiles']\n\t\t\t$parameter.Name | Should -Be 'ShowModifiedFiles'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowProgress' {\n\t\t\t$parameter = (Get-Command Invoke-D365SCDPBundleInstall).Parameters['ShowProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset InstallOnly\" {\n\t\t<#\n\t\tInstallOnly -InstallOnly -Path\n\t\tInstallOnly -InstallOnly -Path -MetaDataDir -ShowModifiedFiles -ShowProgress\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Tfs\" {\n\t\t<#\n\t\tTfs -Path\n\t\tTfs -Command -Path -MetaDataDir -TfsWorkspaceDir -TfsUri -ShowModifiedFiles -ShowProgress\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365SDPInstall.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365SDPInstall Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365SDPInstall).ParameterSets.Name | Should -Be 'QuickInstall', 'DevInstall', 'Manual', 'UDEInstall'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstall).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstall).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter QuickInstallAll' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstall).Parameters['QuickInstallAll']\n\t\t\t$parameter.Name | Should -Be 'QuickInstallAll'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'QuickInstall'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'QuickInstall'\n\t\t\t$parameter.ParameterSets['QuickInstall'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['QuickInstall'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['QuickInstall'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['QuickInstall'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['QuickInstall'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DevInstall' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstall).Parameters['DevInstall']\n\t\t\t$parameter.Name | Should -Be 'DevInstall'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'DevInstall'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'DevInstall'\n\t\t\t$parameter.ParameterSets['DevInstall'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['DevInstall'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['DevInstall'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['DevInstall'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['DevInstall'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Command' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstall).Parameters['Command']\n\t\t\t$parameter.Name | Should -Be 'Command'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Manual'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Manual'\n\t\t\t$parameter.ParameterSets['Manual'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Manual'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['Manual'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Manual'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Manual'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Step' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstall).Parameters['Step']\n\t\t\t$parameter.Name | Should -Be 'Step'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RunbookId' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstall).Parameters['RunbookId']\n\t\t\t$parameter.Name | Should -Be 'RunbookId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstall).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstall).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstall).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter TopologyFile' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstall).Parameters['TopologyFile']\n\t\t\t$parameter.Name | Should -Be 'TopologyFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter UseExistingTopologyFile' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstall).Parameters['UseExistingTopologyFile']\n\t\t\t$parameter.Name | Should -Be 'UseExistingTopologyFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter UnifiedDevelopmentEnvironment' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstall).Parameters['UnifiedDevelopmentEnvironment']\n\t\t\t$parameter.Name | Should -Be 'UnifiedDevelopmentEnvironment'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'UDEInstall'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'UDEInstall'\n\t\t\t$parameter.ParameterSets['UDEInstall'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['UDEInstall'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['UDEInstall'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['UDEInstall'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['UDEInstall'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter IncludeFallbackRetailServiceModels' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstall).Parameters['IncludeFallbackRetailServiceModels']\n\t\t\t$parameter.Name | Should -Be 'IncludeFallbackRetailServiceModels'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstall).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ForceFallbackServiceModels' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstall).Parameters['ForceFallbackServiceModels']\n\t\t\t$parameter.Name | Should -Be 'ForceFallbackServiceModels'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset QuickInstall\" {\n\t\t<#\n\t\tQuickInstall -Path\n\t\tQuickInstall -Path -MetaDataDir -QuickInstallAll -Step -RunbookId -LogPath -ShowOriginalProgress -OutputCommandOnly -TopologyFile -UseExistingTopologyFile -IncludeFallbackRetailServiceModels -Force -ForceFallbackServiceModels\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset DevInstall\" {\n\t\t<#\n\t\tDevInstall -Path\n\t\tDevInstall -Path -MetaDataDir -DevInstall -Step -RunbookId -LogPath -ShowOriginalProgress -OutputCommandOnly -TopologyFile -UseExistingTopologyFile -IncludeFallbackRetailServiceModels -Force -ForceFallbackServiceModels\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Manual\" {\n\t\t<#\n\t\tManual -Path -Command\n\t\tManual -Path -MetaDataDir -Command -Step -RunbookId -LogPath -ShowOriginalProgress -OutputCommandOnly -TopologyFile -UseExistingTopologyFile -IncludeFallbackRetailServiceModels -Force -ForceFallbackServiceModels\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset UDEInstall\" {\n\t\t<#\n\t\tUDEInstall -Path\n\t\tUDEInstall -Path -MetaDataDir -Step -RunbookId -LogPath -ShowOriginalProgress -OutputCommandOnly -TopologyFile -UseExistingTopologyFile -UnifiedDevelopmentEnvironment -IncludeFallbackRetailServiceModels -Force -ForceFallbackServiceModels\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365SDPInstallUDE.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365SDPInstallUDE Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365SDPInstallUDE).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstallUDE).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstallUDE).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstallUDE).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Invoke-D365SDPInstallUDE).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path -MetaDataDir\n\t\t__AllParameterSets -Path -MetaDataDir -LogPath -Force\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365SeleniumDownload.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365SeleniumDownload Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365SeleniumDownload).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter RegressionSuiteAutomationTool' {\n\t\t\t$parameter = (Get-Command Invoke-D365SeleniumDownload).Parameters['RegressionSuiteAutomationTool']\n\t\t\t$parameter.Name | Should -Be 'RegressionSuiteAutomationTool'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PerfSDK' {\n\t\t\t$parameter = (Get-Command Invoke-D365SeleniumDownload).Parameters['PerfSDK']\n\t\t\t$parameter.Name | Should -Be 'PerfSDK'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -RegressionSuiteAutomationTool -PerfSDK\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365SqlScript.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365SqlScript Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365SqlScript).ParameterSets.Name | Should -Be 'FilePath', 'Command'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter FilePath' {\n\t\t\t$parameter = (Get-Command Invoke-D365SqlScript).Parameters['FilePath']\n\t\t\t$parameter.Name | Should -Be 'FilePath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'FilePath'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'FilePath'\n\t\t\t$parameter.ParameterSets['FilePath'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['FilePath'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['FilePath'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['FilePath'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['FilePath'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Command' {\n\t\t\t$parameter = (Get-Command Invoke-D365SqlScript).Parameters['Command']\n\t\t\t$parameter.Name | Should -Be 'Command'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Command'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Command'\n\t\t\t$parameter.ParameterSets['Command'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Command'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Command'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Command'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Command'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Invoke-D365SqlScript).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Invoke-D365SqlScript).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Invoke-D365SqlScript).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Invoke-D365SqlScript).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter TrustedConnection' {\n\t\t\t$parameter = (Get-Command Invoke-D365SqlScript).Parameters['TrustedConnection']\n\t\t\t$parameter.Name | Should -Be 'TrustedConnection'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Boolean\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Invoke-D365SqlScript).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter NoPooling' {\n\t\t\t$parameter = (Get-Command Invoke-D365SqlScript).Parameters['NoPooling']\n\t\t\t$parameter.Name | Should -Be 'NoPooling'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset FilePath\" {\n\t\t<#\n\t\tFilePath -FilePath\n\t\tFilePath -FilePath -DatabaseServer -DatabaseName -SqlUser -SqlPwd -TrustedConnection -EnableException -NoPooling\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Command\" {\n\t\t<#\n\t\tCommand -Command\n\t\tCommand -Command -DatabaseServer -DatabaseName -SqlUser -SqlPwd -TrustedConnection -EnableException -NoPooling\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365SysFlushAodCache.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365SysFlushAodCache Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365SysFlushAodCache).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Url' {\n\t\t\t$parameter = (Get-Command Invoke-D365SysFlushAodCache).Parameters['Url']\n\t\t\t$parameter.Name | Should -Be 'Url'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Url\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365SysRunnerClass.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365SysRunnerClass Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365SysRunnerClass).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ClassName' {\n\t\t\t$parameter = (Get-Command Invoke-D365SysRunnerClass).Parameters['ClassName']\n\t\t\t$parameter.Name | Should -Be 'ClassName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Company' {\n\t\t\t$parameter = (Get-Command Invoke-D365SysRunnerClass).Parameters['Company']\n\t\t\t$parameter.Name | Should -Be 'Company'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Url' {\n\t\t\t$parameter = (Get-Command Invoke-D365SysRunnerClass).Parameters['Url']\n\t\t\t$parameter.Name | Should -Be 'Url'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -ClassName\n\t\tDefault -ClassName -Company -Url\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365TableBrowser.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365TableBrowser Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365TableBrowser).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter TableName' {\n\t\t\t$parameter = (Get-Command Invoke-D365TableBrowser).Parameters['TableName']\n\t\t\t$parameter.Name | Should -Be 'TableName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Company' {\n\t\t\t$parameter = (Get-Command Invoke-D365TableBrowser).Parameters['Company']\n\t\t\t$parameter.Name | Should -Be 'Company'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Url' {\n\t\t\t$parameter = (Get-Command Invoke-D365TableBrowser).Parameters['Url']\n\t\t\t$parameter.Name | Should -Be 'Url'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -TableName\n\t\tDefault -TableName -Company -Url\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365VisualStudioCompilerResultAnalyzer.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365VisualStudioCompilerResultAnalyzer Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365VisualStudioCompilerResultAnalyzer).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Module' {\n\t\t\t$parameter = (Get-Command Invoke-D365VisualStudioCompilerResultAnalyzer).Parameters['Module']\n\t\t\t$parameter.Name | Should -Be 'Module'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Invoke-D365VisualStudioCompilerResultAnalyzer).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SkipWarnings' {\n\t\t\t$parameter = (Get-Command Invoke-D365VisualStudioCompilerResultAnalyzer).Parameters['SkipWarnings']\n\t\t\t$parameter.Name | Should -Be 'SkipWarnings'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SkipTasks' {\n\t\t\t$parameter = (Get-Command Invoke-D365VisualStudioCompilerResultAnalyzer).Parameters['SkipTasks']\n\t\t\t$parameter.Name | Should -Be 'SkipTasks'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Invoke-D365VisualStudioCompilerResultAnalyzer).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Module -OutputPath -SkipWarnings -SkipTasks -PackageDirectory\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Invoke-D365WinRmCertificateRotation.Tests.ps1",
    "content": "﻿Describe \"Invoke-D365WinRmCertificateRotation Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Invoke-D365WinRmCertificateRotation).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter MachineName' {\n\t\t\t$parameter = (Get-Command Invoke-D365WinRmCertificateRotation).Parameters['MachineName']\n\t\t\t$parameter.Name | Should -Be 'MachineName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -MachineName\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/New-D365Bacpac.Tests.ps1",
    "content": "﻿Describe \"New-D365Bacpac Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command New-D365Bacpac).ParameterSets.Name | Should -Be 'ExportTier2', 'ExportTier1'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ExportModeTier1' {\n\t\t\t$parameter = (Get-Command New-D365Bacpac).Parameters['ExportModeTier1']\n\t\t\t$parameter.Name | Should -Be 'ExportModeTier1'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ExportTier1'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ExportTier1'\n\t\t\t$parameter.ParameterSets['ExportTier1'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ExportTier1'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['ExportTier1'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExportTier1'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExportTier1'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ExportModeTier2' {\n\t\t\t$parameter = (Get-Command New-D365Bacpac).Parameters['ExportModeTier2']\n\t\t\t$parameter.Name | Should -Be 'ExportModeTier2'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ExportTier2'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ExportTier2'\n\t\t\t$parameter.ParameterSets['ExportTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ExportTier2'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['ExportTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExportTier2'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExportTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command New-D365Bacpac).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command New-D365Bacpac).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command New-D365Bacpac).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ExportTier2', '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ExportTier2'\n\t\t\t$parameter.ParameterSets['ExportTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ExportTier2'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['ExportTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExportTier2'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['ExportTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command New-D365Bacpac).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ExportTier2', '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ExportTier2'\n\t\t\t$parameter.ParameterSets['ExportTier2'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ExportTier2'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['ExportTier2'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExportTier2'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['ExportTier2'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BackupDirectory' {\n\t\t\t$parameter = (Get-Command New-D365Bacpac).Parameters['BackupDirectory']\n\t\t\t$parameter.Name | Should -Be 'BackupDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ExportTier1'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ExportTier1'\n\t\t\t$parameter.ParameterSets['ExportTier1'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExportTier1'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['ExportTier1'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExportTier1'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExportTier1'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter NewDatabaseName' {\n\t\t\t$parameter = (Get-Command New-D365Bacpac).Parameters['NewDatabaseName']\n\t\t\t$parameter.Name | Should -Be 'NewDatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BacpacFile' {\n\t\t\t$parameter = (Get-Command New-D365Bacpac).Parameters['BacpacFile']\n\t\t\t$parameter.Name | Should -Be 'BacpacFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter CustomSqlFile' {\n\t\t\t$parameter = (Get-Command New-D365Bacpac).Parameters['CustomSqlFile']\n\t\t\t$parameter.Name | Should -Be 'CustomSqlFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DiagnosticFile' {\n\t\t\t$parameter = (Get-Command New-D365Bacpac).Parameters['DiagnosticFile']\n\t\t\t$parameter.Name | Should -Be 'DiagnosticFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ExportOnly' {\n\t\t\t$parameter = (Get-Command New-D365Bacpac).Parameters['ExportOnly']\n\t\t\t$parameter.Name | Should -Be 'ExportOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MaxParallelism' {\n\t\t\t$parameter = (Get-Command New-D365Bacpac).Parameters['MaxParallelism']\n\t\t\t$parameter.Name | Should -Be 'MaxParallelism'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command New-D365Bacpac).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command New-D365Bacpac).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command New-D365Bacpac).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset ExportTier2\" {\n\t\t<#\n\t\tExportTier2 -ExportModeTier2 -SqlUser -SqlPwd\n\t\tExportTier2 -ExportModeTier2 -DatabaseServer -DatabaseName -SqlUser -SqlPwd -NewDatabaseName -BacpacFile -CustomSqlFile -DiagnosticFile -ExportOnly -MaxParallelism -ShowOriginalProgress -OutputCommandOnly -EnableException\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset ExportTier1\" {\n\t\t<#\n\t\tExportTier1 -ExportModeTier1\n\t\tExportTier1 -ExportModeTier1 -DatabaseServer -DatabaseName -SqlUser -SqlPwd -BackupDirectory -NewDatabaseName -BacpacFile -CustomSqlFile -DiagnosticFile -ExportOnly -MaxParallelism -ShowOriginalProgress -OutputCommandOnly -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/New-D365CAReport.Tests.ps1",
    "content": "﻿Describe \"New-D365CAReport Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command New-D365CAReport).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command New-D365CAReport).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Module' {\n\t\t\t$parameter = (Get-Command New-D365CAReport).Parameters['Module']\n\t\t\t$parameter.Name | Should -Be 'Module'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Model' {\n\t\t\t$parameter = (Get-Command New-D365CAReport).Parameters['Model']\n\t\t\t$parameter.Name | Should -Be 'Model'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SuffixWithModule' {\n\t\t\t$parameter = (Get-Command New-D365CAReport).Parameters['SuffixWithModule']\n\t\t\t$parameter.Name | Should -Be 'SuffixWithModule'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command New-D365CAReport).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command New-D365CAReport).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter XmlLog' {\n\t\t\t$parameter = (Get-Command New-D365CAReport).Parameters['XmlLog']\n\t\t\t$parameter.Name | Should -Be 'XmlLog'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackagesRoot' {\n\t\t\t$parameter = (Get-Command New-D365CAReport).Parameters['PackagesRoot']\n\t\t\t$parameter.Name | Should -Be 'PackagesRoot'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command New-D365CAReport).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command New-D365CAReport).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command New-D365CAReport).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Module -Model\n\t\t__AllParameterSets -OutputPath -Module -Model -SuffixWithModule -BinDir -MetaDataDir -XmlLog -PackagesRoot -LogPath -ShowOriginalProgress -OutputCommandOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/New-D365EntraIntegration.Tests.ps1",
    "content": "﻿Describe \"New-D365EntraIntegration Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command New-D365EntraIntegration).ParameterSets.Name | Should -Be 'NewCertificate', 'ExistingCertificate'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ClientId' {\n\t\t\t$parameter = (Get-Command New-D365EntraIntegration).Parameters['ClientId']\n\t\t\t$parameter.Name | Should -Be 'ClientId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ExistingCertificateFile' {\n\t\t\t$parameter = (Get-Command New-D365EntraIntegration).Parameters['ExistingCertificateFile']\n\t\t\t$parameter.Name | Should -Be 'ExistingCertificateFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ExistingCertificate'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ExistingCertificate'\n\t\t\t$parameter.ParameterSets['ExistingCertificate'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['ExistingCertificate'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['ExistingCertificate'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExistingCertificate'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExistingCertificate'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ExistingCertificatePrivateKeyFile' {\n\t\t\t$parameter = (Get-Command New-D365EntraIntegration).Parameters['ExistingCertificatePrivateKeyFile']\n\t\t\t$parameter.Name | Should -Be 'ExistingCertificatePrivateKeyFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'ExistingCertificate'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'ExistingCertificate'\n\t\t\t$parameter.ParameterSets['ExistingCertificate'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExistingCertificate'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['ExistingCertificate'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExistingCertificate'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['ExistingCertificate'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter CertificateName' {\n\t\t\t$parameter = (Get-Command New-D365EntraIntegration).Parameters['CertificateName']\n\t\t\t$parameter.Name | Should -Be 'CertificateName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'NewCertificate'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'NewCertificate'\n\t\t\t$parameter.ParameterSets['NewCertificate'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['NewCertificate'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['NewCertificate'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['NewCertificate'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['NewCertificate'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter CertificateExpirationYears' {\n\t\t\t$parameter = (Get-Command New-D365EntraIntegration).Parameters['CertificateExpirationYears']\n\t\t\t$parameter.Name | Should -Be 'CertificateExpirationYears'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'NewCertificate'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'NewCertificate'\n\t\t\t$parameter.ParameterSets['NewCertificate'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['NewCertificate'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['NewCertificate'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['NewCertificate'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['NewCertificate'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter NewCertificateFile' {\n\t\t\t$parameter = (Get-Command New-D365EntraIntegration).Parameters['NewCertificateFile']\n\t\t\t$parameter.Name | Should -Be 'NewCertificateFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'NewCertificate'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'NewCertificate'\n\t\t\t$parameter.ParameterSets['NewCertificate'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['NewCertificate'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['NewCertificate'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['NewCertificate'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['NewCertificate'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter NewCertificatePrivateKeyFile' {\n\t\t\t$parameter = (Get-Command New-D365EntraIntegration).Parameters['NewCertificatePrivateKeyFile']\n\t\t\t$parameter.Name | Should -Be 'NewCertificatePrivateKeyFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'NewCertificate'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'NewCertificate'\n\t\t\t$parameter.ParameterSets['NewCertificate'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['NewCertificate'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['NewCertificate'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['NewCertificate'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['NewCertificate'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter CertificatePassword' {\n\t\t\t$parameter = (Get-Command New-D365EntraIntegration).Parameters['CertificatePassword']\n\t\t\t$parameter.Name | Should -Be 'CertificatePassword'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Security.SecureString\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command New-D365EntraIntegration).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset NewCertificate\" {\n\t\t<#\n\t\tNewCertificate -ClientId\n\t\tNewCertificate -ClientId -CertificateName -CertificateExpirationYears -NewCertificateFile -NewCertificatePrivateKeyFile -CertificatePassword -Force\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset ExistingCertificate\" {\n\t\t<#\n\t\tExistingCertificate -ClientId -ExistingCertificateFile\n\t\tExistingCertificate -ClientId -ExistingCertificateFile -ExistingCertificatePrivateKeyFile -CertificatePassword -Force\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/New-D365ISVLicense.Tests.ps1",
    "content": "﻿Describe \"New-D365ISVLicense Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command New-D365ISVLicense).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter LicenseFile' {\n\t\t\t$parameter = (Get-Command New-D365ISVLicense).Parameters['LicenseFile']\n\t\t\t$parameter.Name | Should -Be 'LicenseFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command New-D365ISVLicense).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command New-D365ISVLicense).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -LicenseFile\n\t\t__AllParameterSets -LicenseFile -Path -OutputPath\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/New-D365ModuleToRemove.Tests.ps1",
    "content": "﻿Describe \"New-D365ModuleToRemove Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command New-D365ModuleToRemove).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command New-D365ModuleToRemove).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Modules' {\n\t\t\t$parameter = (Get-Command New-D365ModuleToRemove).Parameters['Modules']\n\t\t\t$parameter.Name | Should -Be 'Modules'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -Path -Modules\n\t\tDefault -Path -Modules\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/New-D365TopologyFile.Tests.ps1",
    "content": "﻿Describe \"New-D365TopologyFile Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command New-D365TopologyFile).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command New-D365TopologyFile).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Services' {\n\t\t\t$parameter = (Get-Command New-D365TopologyFile).Parameters['Services']\n\t\t\t$parameter.Name | Should -Be 'Services'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter NewPath' {\n\t\t\t$parameter = (Get-Command New-D365TopologyFile).Parameters['NewPath']\n\t\t\t$parameter.Name | Should -Be 'NewPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -Path -Services -NewPath\n\t\tDefault -Path -Services -NewPath\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Publish-D365SsrsReport.Tests.ps1",
    "content": "﻿Describe \"Publish-D365SsrsReport Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Publish-D365SsrsReport).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Module' {\n\t\t\t$parameter = (Get-Command Publish-D365SsrsReport).Parameters['Module']\n\t\t\t$parameter.Name | Should -Be 'Module'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ReportName' {\n\t\t\t$parameter = (Get-Command Publish-D365SsrsReport).Parameters['ReportName']\n\t\t\t$parameter.Name | Should -Be 'ReportName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogFile' {\n\t\t\t$parameter = (Get-Command Publish-D365SsrsReport).Parameters['LogFile']\n\t\t\t$parameter.Name | Should -Be 'LogFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Publish-D365SsrsReport).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ToolsBasePath' {\n\t\t\t$parameter = (Get-Command Publish-D365SsrsReport).Parameters['ToolsBasePath']\n\t\t\t$parameter.Name | Should -Be 'ToolsBasePath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ReportServerIp' {\n\t\t\t$parameter = (Get-Command Publish-D365SsrsReport).Parameters['ReportServerIp']\n\t\t\t$parameter.Name | Should -Be 'ReportServerIp'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Module -ReportName -LogFile -PackageDirectory -ToolsBasePath -ReportServerIp\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Publish-D365WebResources.Tests.ps1",
    "content": "﻿Describe \"Publish-D365WebResources Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Publish-D365WebResources).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter PackageDirectory' {\n\t\t\t$parameter = (Get-Command Publish-D365WebResources).Parameters['PackageDirectory']\n\t\t\t$parameter.Name | Should -Be 'PackageDirectory'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be PSFramework.Parameter.PathDirectoryParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AosServiceWebRootPath' {\n\t\t\t$parameter = (Get-Command Publish-D365WebResources).Parameters['AosServiceWebRootPath']\n\t\t\t$parameter.Name | Should -Be 'AosServiceWebRootPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be PSFramework.Parameter.PathDirectoryParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -PackageDirectory -AosServiceWebRootPath\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Register-D365AzureStorageConfig.Tests.ps1",
    "content": "﻿Describe \"Register-D365AzureStorageConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Register-D365AzureStorageConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ConfigStorageLocation' {\n\t\t\t$parameter = (Get-Command Register-D365AzureStorageConfig).Parameters['ConfigStorageLocation']\n\t\t\t$parameter.Name | Should -Be 'ConfigStorageLocation'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -ConfigStorageLocation\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Remove-D365BroadcastMessageConfig.Tests.ps1",
    "content": "﻿Describe \"Remove-D365BroadcastMessageConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Remove-D365BroadcastMessageConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Remove-D365BroadcastMessageConfig).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Temporary' {\n\t\t\t$parameter = (Get-Command Remove-D365BroadcastMessageConfig).Parameters['Temporary']\n\t\t\t$parameter.Name | Should -Be 'Temporary'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Name\n\t\t__AllParameterSets -Name -Temporary\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Remove-D365Database.Tests.ps1",
    "content": "﻿Describe \"Remove-D365Database Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Remove-D365Database).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Remove-D365Database).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Remove-D365Database).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Remove-D365Database).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Remove-D365Database).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Remove-D365Database).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Remove-D365Database).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -EnableException -Force\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Remove-D365LcsAssetFile.Tests.ps1",
    "content": "﻿Describe \"Remove-D365LcsAssetFile Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Remove-D365LcsAssetFile).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Remove-D365LcsAssetFile).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AssetId' {\n\t\t\t$parameter = (Get-Command Remove-D365LcsAssetFile).Parameters['AssetId']\n\t\t\t$parameter.Name | Should -Be 'AssetId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Remove-D365LcsAssetFile).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Remove-D365LcsAssetFile).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RetryTimeout' {\n\t\t\t$parameter = (Get-Command Remove-D365LcsAssetFile).Parameters['RetryTimeout']\n\t\t\t$parameter.Name | Should -Be 'RetryTimeout'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.TimeSpan\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Remove-D365LcsAssetFile).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -AssetId\n\t\t__AllParameterSets -ProjectId -AssetId -BearerToken -LcsApiUri -RetryTimeout -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Remove-D365Model.Tests.ps1",
    "content": "﻿Describe \"Remove-D365Model Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Remove-D365Model).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Model' {\n\t\t\t$parameter = (Get-Command Remove-D365Model).Parameters['Model']\n\t\t\t$parameter.Name | Should -Be 'Model'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Remove-D365Model).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MetaDataDir' {\n\t\t\t$parameter = (Get-Command Remove-D365Model).Parameters['MetaDataDir']\n\t\t\t$parameter.Name | Should -Be 'MetaDataDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DeleteFolders' {\n\t\t\t$parameter = (Get-Command Remove-D365Model).Parameters['DeleteFolders']\n\t\t\t$parameter.Name | Should -Be 'DeleteFolders'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Remove-D365Model).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Remove-D365Model).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Model\n\t\t__AllParameterSets -Model -BinDir -MetaDataDir -DeleteFolders -ShowOriginalProgress -OutputCommandOnly\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Remove-D365User.Tests.ps1",
    "content": "﻿Describe \"Remove-D365User Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Remove-D365User).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Remove-D365User).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Remove-D365User).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Remove-D365User).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Remove-D365User).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Email' {\n\t\t\t$parameter = (Get-Command Remove-D365User).Parameters['Email']\n\t\t\t$parameter.Name | Should -Be 'Email'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Email\n\t\t__AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -Email\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Rename-D365ComputerName.Tests.ps1",
    "content": "﻿Describe \"Rename-D365ComputerName Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Rename-D365ComputerName).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter NewName' {\n\t\t\t$parameter = (Get-Command Rename-D365ComputerName).Parameters['NewName']\n\t\t\t$parameter.Name | Should -Be 'NewName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SSRSReportDatabase' {\n\t\t\t$parameter = (Get-Command Rename-D365ComputerName).Parameters['SSRSReportDatabase']\n\t\t\t$parameter.Name | Should -Be 'SSRSReportDatabase'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Rename-D365ComputerName).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Rename-D365ComputerName).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Rename-D365ComputerName).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Rename-D365ComputerName).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LogPath' {\n\t\t\t$parameter = (Get-Command Rename-D365ComputerName).Parameters['LogPath']\n\t\t\t$parameter.Name | Should -Be 'LogPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Rename-D365ComputerName).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputCommandOnly' {\n\t\t\t$parameter = (Get-Command Rename-D365ComputerName).Parameters['OutputCommandOnly']\n\t\t\t$parameter.Name | Should -Be 'OutputCommandOnly'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Rename-D365ComputerName).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -NewName\n\t\t__AllParameterSets -NewName -SSRSReportDatabase -DatabaseServer -DatabaseName -SqlUser -SqlPwd -LogPath -ShowOriginalProgress -OutputCommandOnly -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Rename-D365Instance.Tests.ps1",
    "content": "﻿Describe \"Rename-D365Instance Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Rename-D365Instance).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter NewName' {\n\t\t\t$parameter = (Get-Command Rename-D365Instance).Parameters['NewName']\n\t\t\t$parameter.Name | Should -Be 'NewName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AosServiceWebRootPath' {\n\t\t\t$parameter = (Get-Command Rename-D365Instance).Parameters['AosServiceWebRootPath']\n\t\t\t$parameter.Name | Should -Be 'AosServiceWebRootPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter IISServerApplicationHostConfigFile' {\n\t\t\t$parameter = (Get-Command Rename-D365Instance).Parameters['IISServerApplicationHostConfigFile']\n\t\t\t$parameter.Name | Should -Be 'IISServerApplicationHostConfigFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter HostsFile' {\n\t\t\t$parameter = (Get-Command Rename-D365Instance).Parameters['HostsFile']\n\t\t\t$parameter.Name | Should -Be 'HostsFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BackupExtension' {\n\t\t\t$parameter = (Get-Command Rename-D365Instance).Parameters['BackupExtension']\n\t\t\t$parameter.Name | Should -Be 'BackupExtension'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MRConfigFile' {\n\t\t\t$parameter = (Get-Command Rename-D365Instance).Parameters['MRConfigFile']\n\t\t\t$parameter.Name | Should -Be 'MRConfigFile'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -NewName\n\t\t__AllParameterSets -NewName -AosServiceWebRootPath -IISServerApplicationHostConfigFile -HostsFile -BackupExtension -MRConfigFile\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Repair-D365BacpacModelFile.Tests.ps1",
    "content": "﻿Describe \"Repair-D365BacpacModelFile Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Repair-D365BacpacModelFile).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Repair-D365BacpacModelFile).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Repair-D365BacpacModelFile).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PathRepairSimple' {\n\t\t\t$parameter = (Get-Command Repair-D365BacpacModelFile).Parameters['PathRepairSimple']\n\t\t\t$parameter.Name | Should -Be 'PathRepairSimple'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PathRepairQualifier' {\n\t\t\t$parameter = (Get-Command Repair-D365BacpacModelFile).Parameters['PathRepairQualifier']\n\t\t\t$parameter.Name | Should -Be 'PathRepairQualifier'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter PathRepairReplace' {\n\t\t\t$parameter = (Get-Command Repair-D365BacpacModelFile).Parameters['PathRepairReplace']\n\t\t\t$parameter.Name | Should -Be 'PathRepairReplace'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter KeepFiles' {\n\t\t\t$parameter = (Get-Command Repair-D365BacpacModelFile).Parameters['KeepFiles']\n\t\t\t$parameter.Name | Should -Be 'KeepFiles'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Repair-D365BacpacModelFile).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path\n\t\t__AllParameterSets -Path -OutputPath -PathRepairSimple -PathRepairQualifier -PathRepairReplace -KeepFiles -Force\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Restart-D365Environment.Tests.ps1",
    "content": "﻿Describe \"Restart-D365Environment Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Restart-D365Environment).ParameterSets.Name | Should -Be 'Default', 'Specific'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ComputerName' {\n\t\t\t$parameter = (Get-Command Restart-D365Environment).Parameters['ComputerName']\n\t\t\t$parameter.Name | Should -Be 'ComputerName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific', 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter All' {\n\t\t\t$parameter = (Get-Command Restart-D365Environment).Parameters['All']\n\t\t\t$parameter.Name | Should -Be 'All'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Aos' {\n\t\t\t$parameter = (Get-Command Restart-D365Environment).Parameters['Aos']\n\t\t\t$parameter.Name | Should -Be 'Aos'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Batch' {\n\t\t\t$parameter = (Get-Command Restart-D365Environment).Parameters['Batch']\n\t\t\t$parameter.Name | Should -Be 'Batch'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FinancialReporter' {\n\t\t\t$parameter = (Get-Command Restart-D365Environment).Parameters['FinancialReporter']\n\t\t\t$parameter.Name | Should -Be 'FinancialReporter'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DMF' {\n\t\t\t$parameter = (Get-Command Restart-D365Environment).Parameters['DMF']\n\t\t\t$parameter.Name | Should -Be 'DMF'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Kill' {\n\t\t\t$parameter = (Get-Command Restart-D365Environment).Parameters['Kill']\n\t\t\t$parameter.Name | Should -Be 'Kill'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Restart-D365Environment).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -ComputerName -All -Kill -ShowOriginalProgress\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Specific\" {\n\t\t<#\n\t\tSpecific -\n\t\tSpecific -ComputerName -Aos -Batch -FinancialReporter -DMF -Kill -ShowOriginalProgress\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Restore-D365DevConfig.Tests.ps1",
    "content": "﻿Describe \"Restore-D365DevConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Restore-D365DevConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Restore-D365DevConfig).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Restore-D365DevConfig).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Path -Force\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Restore-D365WebConfig.Tests.ps1",
    "content": "﻿Describe \"Restore-D365WebConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Restore-D365WebConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Restore-D365WebConfig).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Restore-D365WebConfig).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Path -Force\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Send-D365BroadcastMessage.Tests.ps1",
    "content": "﻿Describe \"Send-D365BroadcastMessage Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Send-D365BroadcastMessage).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Tenant' {\n\t\t\t$parameter = (Get-Command Send-D365BroadcastMessage).Parameters['Tenant']\n\t\t\t$parameter.Name | Should -Be 'Tenant'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter URL' {\n\t\t\t$parameter = (Get-Command Send-D365BroadcastMessage).Parameters['URL']\n\t\t\t$parameter.Name | Should -Be 'URL'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ClientId' {\n\t\t\t$parameter = (Get-Command Send-D365BroadcastMessage).Parameters['ClientId']\n\t\t\t$parameter.Name | Should -Be 'ClientId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ClientSecret' {\n\t\t\t$parameter = (Get-Command Send-D365BroadcastMessage).Parameters['ClientSecret']\n\t\t\t$parameter.Name | Should -Be 'ClientSecret'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter TimeZone' {\n\t\t\t$parameter = (Get-Command Send-D365BroadcastMessage).Parameters['TimeZone']\n\t\t\t$parameter.Name | Should -Be 'TimeZone'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter StartTime' {\n\t\t\t$parameter = (Get-Command Send-D365BroadcastMessage).Parameters['StartTime']\n\t\t\t$parameter.Name | Should -Be 'StartTime'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.DateTime\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EndingInMinutes' {\n\t\t\t$parameter = (Get-Command Send-D365BroadcastMessage).Parameters['EndingInMinutes']\n\t\t\t$parameter.Name | Should -Be 'EndingInMinutes'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OnPremise' {\n\t\t\t$parameter = (Get-Command Send-D365BroadcastMessage).Parameters['OnPremise']\n\t\t\t$parameter.Name | Should -Be 'OnPremise'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Tenant -URL -ClientId -ClientSecret -TimeZone -StartTime -EndingInMinutes -OnPremise\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365ActiveAzureStorageConfig.Tests.ps1",
    "content": "﻿Describe \"Set-D365ActiveAzureStorageConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365ActiveAzureStorageConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Set-D365ActiveAzureStorageConfig).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ConfigStorageLocation' {\n\t\t\t$parameter = (Get-Command Set-D365ActiveAzureStorageConfig).Parameters['ConfigStorageLocation']\n\t\t\t$parameter.Name | Should -Be 'ConfigStorageLocation'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Temporary' {\n\t\t\t$parameter = (Get-Command Set-D365ActiveAzureStorageConfig).Parameters['Temporary']\n\t\t\t$parameter.Name | Should -Be 'Temporary'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -Name -ConfigStorageLocation -Temporary\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365ActiveBroadcastMessageConfig.Tests.ps1",
    "content": "﻿Describe \"Set-D365ActiveBroadcastMessageConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365ActiveBroadcastMessageConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Set-D365ActiveBroadcastMessageConfig).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Temporary' {\n\t\t\t$parameter = (Get-Command Set-D365ActiveBroadcastMessageConfig).Parameters['Temporary']\n\t\t\t$parameter.Name | Should -Be 'Temporary'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Name\n\t\t__AllParameterSets -Name -Temporary\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365Admin.Tests.ps1",
    "content": "﻿Describe \"Set-D365Admin Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365Admin).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter AdminSignInName' {\n\t\t\t$parameter = (Get-Command Set-D365Admin).Parameters['AdminSignInName']\n\t\t\t$parameter.Name | Should -Be 'AdminSignInName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Set-D365Admin).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Set-D365Admin).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Set-D365Admin).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Set-D365Admin).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Set-D365Admin).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -AdminSignInName\n\t\t__AllParameterSets -AdminSignInName -DatabaseServer -DatabaseName -SqlUser -SqlPwd -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365AzCopyPath.Tests.ps1",
    "content": "﻿Describe \"Set-D365AzCopyPath Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365AzCopyPath).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Set-D365AzCopyPath).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path\n\t\t__AllParameterSets -Path\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365ClickOnceTrustPrompt.Tests.ps1",
    "content": "﻿Describe \"Set-D365ClickOnceTrustPrompt Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365ClickOnceTrustPrompt).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365DefaultModelForNewProjects.Tests.ps1",
    "content": "﻿Describe \"Set-D365DefaultModelForNewProjects Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365DefaultModelForNewProjects).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Module' {\n\t\t\t$parameter = (Get-Command Set-D365DefaultModelForNewProjects).Parameters['Module']\n\t\t\t$parameter.Name | Should -Be 'Module'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Module\n\t\t__AllParameterSets -Module\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365FavoriteBookmark.Tests.ps1",
    "content": "﻿Describe \"Set-D365FavoriteBookmark Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365FavoriteBookmark).ParameterSets.Name | Should -Be 'D365FO', 'AzureDevOps'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter URL' {\n\t\t\t$parameter = (Get-Command Set-D365FavoriteBookmark).Parameters['URL']\n\t\t\t$parameter.Name | Should -Be 'URL'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter D365FO' {\n\t\t\t$parameter = (Get-Command Set-D365FavoriteBookmark).Parameters['D365FO']\n\t\t\t$parameter.Name | Should -Be 'D365FO'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'D365FO'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'D365FO'\n\t\t\t$parameter.ParameterSets['D365FO'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['D365FO'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['D365FO'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['D365FO'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['D365FO'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AzureDevOps' {\n\t\t\t$parameter = (Get-Command Set-D365FavoriteBookmark).Parameters['AzureDevOps']\n\t\t\t$parameter.Name | Should -Be 'AzureDevOps'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'AzureDevOps'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'AzureDevOps'\n\t\t\t$parameter.ParameterSets['AzureDevOps'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['AzureDevOps'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['AzureDevOps'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['AzureDevOps'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['AzureDevOps'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset D365FO\" {\n\t\t<#\n\t\tD365FO -\n\t\tD365FO -URL -D365FO\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset AzureDevOps\" {\n\t\t<#\n\t\tAzureDevOps -\n\t\tAzureDevOps -URL -AzureDevOps\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365FlightServiceCatalogId.Tests.ps1",
    "content": "﻿Describe \"Set-D365FlightServiceCatalogId Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365FlightServiceCatalogId).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter FlightServiceCatalogId' {\n\t\t\t$parameter = (Get-Command Set-D365FlightServiceCatalogId).Parameters['FlightServiceCatalogId']\n\t\t\t$parameter.Name | Should -Be 'FlightServiceCatalogId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AosServiceWebRootPath' {\n\t\t\t$parameter = (Get-Command Set-D365FlightServiceCatalogId).Parameters['AosServiceWebRootPath']\n\t\t\t$parameter.Name | Should -Be 'AosServiceWebRootPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -FlightServiceCatalogId -AosServiceWebRootPath\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365LcsApiConfig.Tests.ps1",
    "content": "﻿Describe \"Set-D365LcsApiConfig Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365LcsApiConfig).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProjectId' {\n\t\t\t$parameter = (Get-Command Set-D365LcsApiConfig).Parameters['ProjectId']\n\t\t\t$parameter.Name | Should -Be 'ProjectId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ClientId' {\n\t\t\t$parameter = (Get-Command Set-D365LcsApiConfig).Parameters['ClientId']\n\t\t\t$parameter.Name | Should -Be 'ClientId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BearerToken' {\n\t\t\t$parameter = (Get-Command Set-D365LcsApiConfig).Parameters['BearerToken']\n\t\t\t$parameter.Name | Should -Be 'BearerToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ActiveTokenExpiresOn' {\n\t\t\t$parameter = (Get-Command Set-D365LcsApiConfig).Parameters['ActiveTokenExpiresOn']\n\t\t\t$parameter.Name | Should -Be 'ActiveTokenExpiresOn'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int64\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RefreshToken' {\n\t\t\t$parameter = (Get-Command Set-D365LcsApiConfig).Parameters['RefreshToken']\n\t\t\t$parameter.Name | Should -Be 'RefreshToken'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter LcsApiUri' {\n\t\t\t$parameter = (Get-Command Set-D365LcsApiConfig).Parameters['LcsApiUri']\n\t\t\t$parameter.Name | Should -Be 'LcsApiUri'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Temporary' {\n\t\t\t$parameter = (Get-Command Set-D365LcsApiConfig).Parameters['Temporary']\n\t\t\t$parameter.Name | Should -Be 'Temporary'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -ProjectId -ClientId -BearerToken -ActiveTokenExpiresOn -RefreshToken -LcsApiUri -Temporary\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365NugetPath.Tests.ps1",
    "content": "﻿Describe \"Set-D365NugetPath Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365NugetPath).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Set-D365NugetPath).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path\n\t\t__AllParameterSets -Path\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365OfflineAuthenticationAdminEmail.Tests.ps1",
    "content": "﻿Describe \"Set-D365OfflineAuthenticationAdminEmail Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365OfflineAuthenticationAdminEmail).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Email' {\n\t\t\t$parameter = (Get-Command Set-D365OfflineAuthenticationAdminEmail).Parameters['Email']\n\t\t\t$parameter.Name | Should -Be 'Email'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -Email\n\t\tDefault -Email\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365RsatConfiguration.Tests.ps1",
    "content": "﻿Describe \"Set-D365RsatConfiguration Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365RsatConfiguration).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter LogGenerationEnabled' {\n\t\t\t$parameter = (Get-Command Set-D365RsatConfiguration).Parameters['LogGenerationEnabled']\n\t\t\t$parameter.Name | Should -Be 'LogGenerationEnabled'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Boolean\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter VerboseSnapshotsEnabled' {\n\t\t\t$parameter = (Get-Command Set-D365RsatConfiguration).Parameters['VerboseSnapshotsEnabled']\n\t\t\t$parameter.Name | Should -Be 'VerboseSnapshotsEnabled'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Boolean\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter AddOperatorFieldsToExcelValidationEnabled' {\n\t\t\t$parameter = (Get-Command Set-D365RsatConfiguration).Parameters['AddOperatorFieldsToExcelValidationEnabled']\n\t\t\t$parameter.Name | Should -Be 'AddOperatorFieldsToExcelValidationEnabled'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Boolean\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter RSATConfigFilename' {\n\t\t\t$parameter = (Get-Command Set-D365RsatConfiguration).Parameters['RSATConfigFilename']\n\t\t\t$parameter.Name | Should -Be 'RSATConfigFilename'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Object\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -LogGenerationEnabled -VerboseSnapshotsEnabled -AddOperatorFieldsToExcelValidationEnabled -RSATConfigFilename\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365RsatTier2Crypto.Tests.ps1",
    "content": "﻿Describe \"Set-D365RsatTier2Crypto Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365RsatTier2Crypto).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365SDPCleanUp.Tests.ps1",
    "content": "﻿Describe \"Set-D365SDPCleanUp Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365SDPCleanUp).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter NumberOfDays' {\n\t\t\t$parameter = (Get-Command Set-D365SDPCleanUp).Parameters['NumberOfDays']\n\t\t\t$parameter.Name | Should -Be 'NumberOfDays'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -NumberOfDays\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365SqlPackagePath.Tests.ps1",
    "content": "﻿Describe \"Set-D365SqlPackagePath Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365SqlPackagePath).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Set-D365SqlPackagePath).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Path\n\t\t__AllParameterSets -Path\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365StartPage.Tests.ps1",
    "content": "﻿Describe \"Set-D365StartPage Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365StartPage).ParameterSets.Name | Should -Be 'Default', 'Url'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Name' {\n\t\t\t$parameter = (Get-Command Set-D365StartPage).Parameters['Name']\n\t\t\t$parameter.Name | Should -Be 'Name'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Url' {\n\t\t\t$parameter = (Get-Command Set-D365StartPage).Parameters['Url']\n\t\t\t$parameter.Name | Should -Be 'Url'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Url'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Url'\n\t\t\t$parameter.ParameterSets['Url'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['Url'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Url'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Url'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['Url'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -Name\n\t\tDefault -Name\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Url\" {\n\t\t<#\n\t\tUrl -Url\n\t\tUrl -Url\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365SysAdmin.Tests.ps1",
    "content": "﻿Describe \"Set-D365SysAdmin Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365SysAdmin).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter User' {\n\t\t\t$parameter = (Get-Command Set-D365SysAdmin).Parameters['User']\n\t\t\t$parameter.Name | Should -Be 'User'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Set-D365SysAdmin).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Set-D365SysAdmin).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Set-D365SysAdmin).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Set-D365SysAdmin).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -User -DatabaseServer -DatabaseName -SqlUser -SqlPwd\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365TraceParserFileSize.Tests.ps1",
    "content": "﻿Describe \"Set-D365TraceParserFileSize Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365TraceParserFileSize).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter FileSizeInMB' {\n\t\t\t$parameter = (Get-Command Set-D365TraceParserFileSize).Parameters['FileSizeInMB']\n\t\t\t$parameter.Name | Should -Be 'FileSizeInMB'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Set-D365TraceParserFileSize).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -FileSizeInMB\n\t\t__AllParameterSets -FileSizeInMB -Path\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365WebConfigDatabase.Tests.ps1",
    "content": "﻿Describe \"Set-D365WebConfigDatabase Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365WebConfigDatabase).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Set-D365WebConfigDatabase).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Set-D365WebConfigDatabase).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Set-D365WebConfigDatabase).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Set-D365WebConfigDatabase).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Set-D365WebConfigDatabase).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Object\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd\n\t\t__AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -Path\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365WebServerType.Tests.ps1",
    "content": "﻿Describe \"Set-D365WebServerType Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365WebServerType).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter RuntimeHostType' {\n\t\t\t$parameter = (Get-Command Set-D365WebServerType).Parameters['RuntimeHostType']\n\t\t\t$parameter.Name | Should -Be 'RuntimeHostType'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -RuntimeHostType\n\t\t__AllParameterSets -RuntimeHostType\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Set-D365WorkstationMode.Tests.ps1",
    "content": "﻿Describe \"Set-D365WorkstationMode Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Set-D365WorkstationMode).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Enabled' {\n\t\t\t$parameter = (Get-Command Set-D365WorkstationMode).Parameters['Enabled']\n\t\t\t$parameter.Name | Should -Be 'Enabled'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Boolean\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Enabled\n\t\t__AllParameterSets -Enabled\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Start-D365Environment.Tests.ps1",
    "content": "﻿Describe \"Start-D365Environment Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Start-D365Environment).ParameterSets.Name | Should -Be 'Default', 'Specific'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ComputerName' {\n\t\t\t$parameter = (Get-Command Start-D365Environment).Parameters['ComputerName']\n\t\t\t$parameter.Name | Should -Be 'ComputerName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific', 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter All' {\n\t\t\t$parameter = (Get-Command Start-D365Environment).Parameters['All']\n\t\t\t$parameter.Name | Should -Be 'All'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Aos' {\n\t\t\t$parameter = (Get-Command Start-D365Environment).Parameters['Aos']\n\t\t\t$parameter.Name | Should -Be 'Aos'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Batch' {\n\t\t\t$parameter = (Get-Command Start-D365Environment).Parameters['Batch']\n\t\t\t$parameter.Name | Should -Be 'Batch'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FinancialReporter' {\n\t\t\t$parameter = (Get-Command Start-D365Environment).Parameters['FinancialReporter']\n\t\t\t$parameter.Name | Should -Be 'FinancialReporter'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DMF' {\n\t\t\t$parameter = (Get-Command Start-D365Environment).Parameters['DMF']\n\t\t\t$parameter.Name | Should -Be 'DMF'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OnlyStartTypeAutomatic' {\n\t\t\t$parameter = (Get-Command Start-D365Environment).Parameters['OnlyStartTypeAutomatic']\n\t\t\t$parameter.Name | Should -Be 'OnlyStartTypeAutomatic'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Start-D365Environment).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -ComputerName -All -OnlyStartTypeAutomatic -ShowOriginalProgress\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Specific\" {\n\t\t<#\n\t\tSpecific -\n\t\tSpecific -ComputerName -Aos -Batch -FinancialReporter -DMF -OnlyStartTypeAutomatic -ShowOriginalProgress\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Start-D365EnvironmentV2.Tests.ps1",
    "content": "﻿Describe \"Start-D365EnvironmentV2 Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Start-D365EnvironmentV2).ParameterSets.Name | Should -Be 'Default', 'Specific'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter All' {\n\t\t\t$parameter = (Get-Command Start-D365EnvironmentV2).Parameters['All']\n\t\t\t$parameter.Name | Should -Be 'All'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Aos' {\n\t\t\t$parameter = (Get-Command Start-D365EnvironmentV2).Parameters['Aos']\n\t\t\t$parameter.Name | Should -Be 'Aos'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Batch' {\n\t\t\t$parameter = (Get-Command Start-D365EnvironmentV2).Parameters['Batch']\n\t\t\t$parameter.Name | Should -Be 'Batch'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FinancialReporter' {\n\t\t\t$parameter = (Get-Command Start-D365EnvironmentV2).Parameters['FinancialReporter']\n\t\t\t$parameter.Name | Should -Be 'FinancialReporter'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DMF' {\n\t\t\t$parameter = (Get-Command Start-D365EnvironmentV2).Parameters['DMF']\n\t\t\t$parameter.Name | Should -Be 'DMF'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OnlyStartTypeAutomatic' {\n\t\t\t$parameter = (Get-Command Start-D365EnvironmentV2).Parameters['OnlyStartTypeAutomatic']\n\t\t\t$parameter.Name | Should -Be 'OnlyStartTypeAutomatic'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Start-D365EnvironmentV2).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -All -OnlyStartTypeAutomatic -ShowOriginalProgress\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Specific\" {\n\t\t<#\n\t\tSpecific -\n\t\tSpecific -Aos -Batch -FinancialReporter -DMF -OnlyStartTypeAutomatic -ShowOriginalProgress\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Start-D365EventTrace.Tests.ps1",
    "content": "﻿Describe \"Start-D365EventTrace Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Start-D365EventTrace).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ProviderName' {\n\t\t\t$parameter = (Get-Command Start-D365EventTrace).Parameters['ProviderName']\n\t\t\t$parameter.Name | Should -Be 'ProviderName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Start-D365EventTrace).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SessionName' {\n\t\t\t$parameter = (Get-Command Start-D365EventTrace).Parameters['SessionName']\n\t\t\t$parameter.Name | Should -Be 'SessionName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FileName' {\n\t\t\t$parameter = (Get-Command Start-D365EventTrace).Parameters['FileName']\n\t\t\t$parameter.Name | Should -Be 'FileName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputFormat' {\n\t\t\t$parameter = (Get-Command Start-D365EventTrace).Parameters['OutputFormat']\n\t\t\t$parameter.Name | Should -Be 'OutputFormat'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MinBuffer' {\n\t\t\t$parameter = (Get-Command Start-D365EventTrace).Parameters['MinBuffer']\n\t\t\t$parameter.Name | Should -Be 'MinBuffer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MaxBuffer' {\n\t\t\t$parameter = (Get-Command Start-D365EventTrace).Parameters['MaxBuffer']\n\t\t\t$parameter.Name | Should -Be 'MaxBuffer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter BufferSizeKB' {\n\t\t\t$parameter = (Get-Command Start-D365EventTrace).Parameters['BufferSizeKB']\n\t\t\t$parameter.Name | Should -Be 'BufferSizeKB'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter MaxLogFileSizeMB' {\n\t\t\t$parameter = (Get-Command Start-D365EventTrace).Parameters['MaxLogFileSizeMB']\n\t\t\t$parameter.Name | Should -Be 'MaxLogFileSizeMB'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Int32\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -ProviderName\n\t\t__AllParameterSets -ProviderName -OutputPath -SessionName -FileName -OutputFormat -MinBuffer -MaxBuffer -BufferSizeKB -MaxLogFileSizeMB\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Stop-D365Environment.Tests.ps1",
    "content": "﻿Describe \"Stop-D365Environment Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Stop-D365Environment).ParameterSets.Name | Should -Be 'Default', 'Specific'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter ComputerName' {\n\t\t\t$parameter = (Get-Command Stop-D365Environment).Parameters['ComputerName']\n\t\t\t$parameter.Name | Should -Be 'ComputerName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String[]\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific', 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter All' {\n\t\t\t$parameter = (Get-Command Stop-D365Environment).Parameters['All']\n\t\t\t$parameter.Name | Should -Be 'All'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Aos' {\n\t\t\t$parameter = (Get-Command Stop-D365Environment).Parameters['Aos']\n\t\t\t$parameter.Name | Should -Be 'Aos'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Batch' {\n\t\t\t$parameter = (Get-Command Stop-D365Environment).Parameters['Batch']\n\t\t\t$parameter.Name | Should -Be 'Batch'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter FinancialReporter' {\n\t\t\t$parameter = (Get-Command Stop-D365Environment).Parameters['FinancialReporter']\n\t\t\t$parameter.Name | Should -Be 'FinancialReporter'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DMF' {\n\t\t\t$parameter = (Get-Command Stop-D365Environment).Parameters['DMF']\n\t\t\t$parameter.Name | Should -Be 'DMF'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Kill' {\n\t\t\t$parameter = (Get-Command Stop-D365Environment).Parameters['Kill']\n\t\t\t$parameter.Name | Should -Be 'Kill'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default', 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 6\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowOriginalProgress' {\n\t\t\t$parameter = (Get-Command Stop-D365Environment).Parameters['ShowOriginalProgress']\n\t\t\t$parameter.Name | Should -Be 'ShowOriginalProgress'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be 'Default', 'Specific'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Default'\n\t\t\t$parameter.ParameterSets['Default'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain 'Specific'\n\t\t\t$parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].Position | Should -Be 7\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -ComputerName -All -Kill -ShowOriginalProgress\n\t\t#>\n\t}\n \tDescribe \"Testing parameterset Specific\" {\n\t\t<#\n\t\tSpecific -\n\t\tSpecific -ComputerName -Aos -Batch -FinancialReporter -DMF -Kill -ShowOriginalProgress\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Stop-D365EventTrace.Tests.ps1",
    "content": "﻿Describe \"Stop-D365EventTrace Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Stop-D365EventTrace).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter SessionName' {\n\t\t\t$parameter = (Get-Command Stop-D365EventTrace).Parameters['SessionName']\n\t\t\t$parameter.Name | Should -Be 'SessionName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -SessionName\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Switch-D365ActiveDatabase.Tests.ps1",
    "content": "﻿Describe \"Switch-D365ActiveDatabase Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Switch-D365ActiveDatabase).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Switch-D365ActiveDatabase).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Switch-D365ActiveDatabase).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Switch-D365ActiveDatabase).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Switch-D365ActiveDatabase).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SourceDatabaseName' {\n\t\t\t$parameter = (Get-Command Switch-D365ActiveDatabase).Parameters['SourceDatabaseName']\n\t\t\t$parameter.Name | Should -Be 'SourceDatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DestinationSuffix' {\n\t\t\t$parameter = (Get-Command Switch-D365ActiveDatabase).Parameters['DestinationSuffix']\n\t\t\t$parameter.Name | Should -Be 'DestinationSuffix'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter EnableException' {\n\t\t\t$parameter = (Get-Command Switch-D365ActiveDatabase).Parameters['EnableException']\n\t\t\t$parameter.Name | Should -Be 'EnableException'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -SourceDatabaseName\n\t\t__AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -SourceDatabaseName -DestinationSuffix -EnableException\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Test-D365Command.Tests.ps1",
    "content": "﻿Describe \"Test-D365Command Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Test-D365Command).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter CommandText' {\n\t\t\t$parameter = (Get-Command Test-D365Command).Parameters['CommandText']\n\t\t\t$parameter.Name | Should -Be 'CommandText'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Mode' {\n\t\t\t$parameter = (Get-Command Test-D365Command).Parameters['Mode']\n\t\t\t$parameter.Name | Should -Be 'Mode'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SplatInput' {\n\t\t\t$parameter = (Get-Command Test-D365Command).Parameters['SplatInput']\n\t\t\t$parameter.Name | Should -Be 'SplatInput'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Collections.Hashtable\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowSplatStyleV1' {\n\t\t\t$parameter = (Get-Command Test-D365Command).Parameters['ShowSplatStyleV1']\n\t\t\t$parameter.Name | Should -Be 'ShowSplatStyleV1'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter ShowSplatStyleV2' {\n\t\t\t$parameter = (Get-Command Test-D365Command).Parameters['ShowSplatStyleV2']\n\t\t\t$parameter.Name | Should -Be 'ShowSplatStyleV2'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter IncludeHelp' {\n\t\t\t$parameter = (Get-Command Test-D365Command).Parameters['IncludeHelp']\n\t\t\t$parameter.Name | Should -Be 'IncludeHelp'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -CommandText -Mode\n\t\t__AllParameterSets -CommandText -Mode -SplatInput -ShowSplatStyleV1 -ShowSplatStyleV2 -IncludeHelp\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Test-D365DataverseConnection.Tests.ps1",
    "content": "﻿Describe \"Test-D365DataverseConnection Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Test-D365DataverseConnection).ParameterSets.Name | Should -Be 'Default'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter BinDir' {\n\t\t\t$parameter = (Get-Command Test-D365DataverseConnection).Parameters['BinDir']\n\t\t\t$parameter.Name | Should -Be 'BinDir'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset Default\" {\n\t\t<#\n\t\tDefault -\n\t\tDefault -BinDir\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Test-D365EntraIntegration.Tests.ps1",
    "content": "﻿Describe \"Test-D365EntraIntegration Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Test-D365EntraIntegration).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Test-D365FlightServiceCatalogId.Tests.ps1",
    "content": "﻿Describe \"Test-D365FlightServiceCatalogId Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Test-D365FlightServiceCatalogId).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter AosServiceWebRootPath' {\n\t\t\t$parameter = (Get-Command Test-D365FlightServiceCatalogId).Parameters['AosServiceWebRootPath']\n\t\t\t$parameter.Name | Should -Be 'AosServiceWebRootPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -\n\t\t__AllParameterSets -AosServiceWebRootPath\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Test-D365LabelIdIsValid.Tests.ps1",
    "content": "﻿Describe \"Test-D365LabelIdIsValid Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Test-D365LabelIdIsValid).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter LabelId' {\n\t\t\t$parameter = (Get-Command Test-D365LabelIdIsValid).Parameters['LabelId']\n\t\t\t$parameter.Name | Should -Be 'LabelId'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -LabelId\n\t\t__AllParameterSets -LabelId\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Update-D365BacpacModelFileSingleTable.Tests.ps1",
    "content": "﻿Describe \"Update-D365BacpacModelFileSingleTable Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Update-D365BacpacModelFileSingleTable).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter Path' {\n\t\t\t$parameter = (Get-Command Update-D365BacpacModelFileSingleTable).Parameters['Path']\n\t\t\t$parameter.Name | Should -Be 'Path'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Table' {\n\t\t\t$parameter = (Get-Command Update-D365BacpacModelFileSingleTable).Parameters['Table']\n\t\t\t$parameter.Name | Should -Be 'Table'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Schema' {\n\t\t\t$parameter = (Get-Command Update-D365BacpacModelFileSingleTable).Parameters['Schema']\n\t\t\t$parameter.Name | Should -Be 'Schema'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter OutputPath' {\n\t\t\t$parameter = (Get-Command Update-D365BacpacModelFileSingleTable).Parameters['OutputPath']\n\t\t\t$parameter.Name | Should -Be 'OutputPath'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Force' {\n\t\t\t$parameter = (Get-Command Update-D365BacpacModelFileSingleTable).Parameters['Force']\n\t\t\t$parameter.Name | Should -Be 'Force'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Table\n\t\t__AllParameterSets -Path -Table -Schema -OutputPath -Force\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/functions/Update-D365User.Tests.ps1",
    "content": "﻿Describe \"Update-D365User Unit Tests\" -Tag \"Unit\" {\n\tBeforeAll {\n\t\t# Place here all things needed to prepare for the tests\n\t}\n\tAfterAll {\n\t\t# Here is where all the cleanup tasks go\n\t}\n\t\n\tDescribe \"Ensuring unchanged command signature\" {\n\t\tIt \"should have the expected parameter sets\" {\n\t\t\t(Get-Command Update-D365User).ParameterSets.Name | Should -Be '__AllParameterSets'\n\t\t}\n\t\t\n\t\tIt 'Should have the expected parameter DatabaseServer' {\n\t\t\t$parameter = (Get-Command Update-D365User).Parameters['DatabaseServer']\n\t\t\t$parameter.Name | Should -Be 'DatabaseServer'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter DatabaseName' {\n\t\t\t$parameter = (Get-Command Update-D365User).Parameters['DatabaseName']\n\t\t\t$parameter.Name | Should -Be 'DatabaseName'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlUser' {\n\t\t\t$parameter = (Get-Command Update-D365User).Parameters['SqlUser']\n\t\t\t$parameter.Name | Should -Be 'SqlUser'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter SqlPwd' {\n\t\t\t$parameter = (Get-Command Update-D365User).Parameters['SqlPwd']\n\t\t\t$parameter.Name | Should -Be 'SqlPwd'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Email' {\n\t\t\t$parameter = (Get-Command Update-D365User).Parameters['Email']\n\t\t\t$parameter.Name | Should -Be 'Email'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t\tIt 'Should have the expected parameter Company' {\n\t\t\t$parameter = (Get-Command Update-D365User).Parameters['Company']\n\t\t\t$parameter.Name | Should -Be 'Company'\n\t\t\t$parameter.ParameterType.ToString() | Should -Be System.String\n\t\t\t$parameter.IsDynamic | Should -Be $False\n\t\t\t$parameter.ParameterSets.Keys | Should -Be '__AllParameterSets'\n\t\t\t$parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets'\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False\n\t\t\t$parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False\n\t\t}\n\t}\n\t\n\tDescribe \"Testing parameterset __AllParameterSets\" {\n\t\t<#\n\t\t__AllParameterSets -Email\n\t\t__AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -Email -Company\n\t\t#>\n\t}\n\n}"
  },
  {
    "path": "d365fo.tools/tests/general/FileIntegrity.Exceptions.ps1",
    "content": "﻿# List of forbidden commands\n$global:BannedCommands = @(\n\t'Write-Host',\n\t'Write-Verbose',\n\t'Write-Warning',\n\t'Write-Error',\n\t'Write-Output',\n\t'Write-Information',\n\t'Write-Debug'\n)\n\n<#\n\tContains list of exceptions for banned cmdlets.\n\tInsert the file names of files that may contain them.\n\t\n\tExample:\n\t\"Write-Host\"  = @('Write-PSFHostColor.ps1','Write-PSFMessage.ps1')\n#>\n$global:MayContainCommand = @{\n\t\"Write-Host\"  = @()\n\t\"Write-Verbose\" = @('invoke-d365dbsync.ps1','invoke-d365dbsyncpartial.ps1')\n\t\"Write-Warning\" = @()\n\t\"Write-Error\"  = @()\n\t\"Write-Output\" = @('convertto-hashtable.ps1')\n\t\"Write-Information\" = @()\n\t\"Write-Debug\" = @()\n}\n\n$global:MayContainAlias = @(\n\t'Initialize-D365RsatCertificate'\n\t, 'Add-D365RsatWifConfigAuthorityThumbprint'\n)\n\n"
  },
  {
    "path": "d365fo.tools/tests/general/FileIntegrity.Tests.ps1",
    "content": "﻿$moduleRoot = (Resolve-Path \"$PSScriptRoot\\..\\..\").Path\n\n. \"$PSScriptRoot\\FileIntegrity.Exceptions.ps1\"\n\nfunction Get-FileEncoding {\n    <#\n\t.SYNOPSIS\n\t\tTests a file for encoding.\n\t\n\t.DESCRIPTION\n\t\tTests a file for encoding.\n\t\n\t.PARAMETER Path\n\t\tThe file to test\n#>\n    [CmdletBinding()]\n    Param (\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [Alias('FullName')]\n        [string]\n        $Path\n    )\n\t\n    [byte[]]$byte = get-content -Encoding byte -ReadCount 4 -TotalCount 4 -Path $Path\n\t\n    if ($byte[0] -eq 0xef -and $byte[1] -eq 0xbb -and $byte[2] -eq 0xbf) { 'UTF8' }\n    elseif ($byte[0] -eq 0xfe -and $byte[1] -eq 0xff) { 'Unicode' }\n    elseif ($byte[0] -eq 0 -and $byte[1] -eq 0 -and $byte[2] -eq 0xfe -and $byte[3] -eq 0xff) { 'UTF32' }\n    elseif ($byte[0] -eq 0x2b -and $byte[1] -eq 0x2f -and $byte[2] -eq 0x76) { 'UTF7' }\n    else { 'Unknown' }\n}\n\nDescribe \"Verifying integrity of module files\" {\n    Context \"Validating PS1 Script files\" {\n        $allFiles = Get-ChildItem -Path $moduleRoot -Recurse -Filter \"*.ps1\" | Where-Object FullName -NotLike \"$moduleRoot\\tests\\*\"\n\t\t\n        foreach ($file in $allFiles) {\n            $name = $file.FullName.Replace(\"$moduleRoot\\\", '')\n\t\t\t\n            It \"[$name] Should have UTF8 encoding\" {\n                Get-FileEncoding -Path $file.FullName | Should -Be 'UTF8'\n            }\n\t\t\t\n            It \"[$name] Should have no trailing space\" {\n                ($file | Select-String \"\\s$\" | Where-Object { $_.Line.Trim().Length -gt 0}).LineNumber | Should -BeNullOrEmpty\n            }\n\t\t\t\n            $tokens = $null\n            $parseErrors = $null\n            $ast = [System.Management.Automation.Language.Parser]::ParseFile($file.FullName, [ref]$tokens, [ref]$parseErrors)\n\t\t\t\n            It \"[$name] Should have no syntax errors\" {\n                $parseErrors | Should Be $Null\n            }\n\t\t\t\n            foreach ($command in $global:BannedCommands) {\n                if ($global:MayContainCommand[\"$command\"] -notcontains $file.Name) {\n                    It \"[$name] Should not use $command\" {\n                        $tokens | Where-Object Text -EQ $command | Should -BeNullOrEmpty\n                    }\n                }\n            }\n\t\t\t\n            It \"[$name] Should not contain aliases\" {\n                if ($global:MayContainAlias -notcontains $file.Name) {\n                    $tokens | Where-Object TokenFlags -eq CommandName | Where-Object { Test-Path \"alias:\\$($_.Text)\" } | Measure-Object | Select-Object -ExpandProperty Count | Should -Be 0\n                }\n            }\n        }\n    }\n\t\n    Context \"Validating help.txt help files\" {\n        $allFiles = Get-ChildItem -Path $moduleRoot -Recurse -Filter \"*.help.txt\" | Where-Object FullName -NotLike \"$moduleRoot\\tests\\*\"\n\t\t\n        foreach ($file in $allFiles) {\n            $name = $file.FullName.Replace(\"$moduleRoot\\\", '')\n\t\t\t\n            It \"[$name] Should have UTF8 encoding\" {\n                Get-FileEncoding -Path $file.FullName | Should -Be 'UTF8'\n            }\n\t\t\t\n            It \"[$name] Should have no trailing space\" {\n                ($file | Select-String \"\\s$\" | Where-Object { $_.Line.Trim().Length -gt 0 } | Measure-Object).Count | Should -Be 0\n            }\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/tests/general/Help.Example.Parameters.Tests.ps1",
    "content": "﻿$excludeCommands = @(\n      'Invoke-D365SCDPBundleInstall'\n    , 'Test-D365Command'\n    , 'Test-PathExists'\n)\n\n$excludeParameters = @(\n    'EnableException'\n    , 'TrustedConnection'\n    , 'Force'\n    , 'Temporary'\n    , 'OutputCommandOnly'\n    , 'ShowOriginalProgress'\n    , 'OutputAsHashtable'\n    , 'LogPath'\n    , 'FailOnErrorMessage'\n)\n\n$commandsRaw = Get-Command -Module d365fo.tools\n\nif ($excludeCommands.Count -gt 0) {\n    $commands = $commandsRaw | Select-String -Pattern $excludeCommands -SimpleMatch -NotMatch\n\n}\nelse {\n    $commands = $commandsRaw\n}\n\nforeach ( $commandName in $commands) {\n    if ($commandName -notlike \"*d365*\") {\n        continue\n    }\n    \n    # command to be tested\n\n    # get all examples from the help\n    $examples = Get-Help $commandName -Examples\n\n    $parameters = (Get-Help $commandName -Full).parameters\n\n    # make a describe block that will contain tests for this\n    Describe \"Parameters without default vaules from $commandName\" {\n        \n        foreach ($parm in $parameters.parameter) {\n            if ($parm.defaultValue -ne \"False\") { continue }\n            \n            $parmName = $parm.name\n            \n            if ($parmName -in $excludeParameters) { continue }\n\n            $res = $false\n\n            foreach ($exampleObject in $examples.Examples.Example) {\n                if ($res) { continue }\n\n                $example = $exampleObject.Code -replace \"`n.*\" -replace \"PS C:\\\\>\"\n\n                $res = $example -match \"-$parmName( *|\\:)\"\n            }\n\n            It \"$parmName is present in an example\" {\n                $res | Should -BeTrue\n            }\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/tests/general/Help.Example.Tests.ps1",
    "content": "﻿$excludeCommands = @(\n    \"Import-ModuleFile\"\n    , \"Get-DeepClone\"\n    , \"Test-TrustedConnection\"\n    , \"Select-DefaultView\"\n    , 'QueryDataSourceRecursion'\n    , 'Get-AxDataEntities'\n)\n\nenum LcsAssetFileType {\n    Model = 1\n    ProcessDataPackage = 4\n    SoftwareDeployablePackage = 10\n    GERConfiguration = 12\n    DataPackage = 15\n    PowerBIReportModel = 19\n}\n\n$commandsRaw = Get-Command -Module d365fo.tools\n\nif ($excludeCommands.Count -gt 0) {\n    $commands = $commandsRaw | Select-String -Pattern $excludeCommands -SimpleMatch -NotMatch\n\n} else {\n    $commands = $commandsRaw\n}\n\nforeach ( $commandName in $commands) {\n    # command to be tested\n    \n    # get all examples from the help\n    $examples = Get-Help $commandName -Examples\n\n    # make a describe block that will contain tests for this\n    Describe \"Examples from $commandName\" {\n        $examples.Examples.Example | foreach {\n            # examples have different format,\n            # at least the ones I used that MS provided\n            # so you need to either standardize them,\n            # or provide some hints about what to do\n            # such as putting the code first\n            # followed by\n            #   #output: the desired output\n\n            # here I am simply taking the first line and removing 'PS C:\\>'\n            # which makes some of the tests fail\n            $example = $_.Code -replace \"`n.*\" -replace \"PS C:\\\\>\"\n\n            if ( ($example -like \"*|*\" ) -or (-not ($example -match $commandName)) -or ($example -like \"*).*\")) {\n                It \"Example - $example\" -Skip { $true }\n            } elseif ($example -match '(?<=^(([^\"|^'']\\*(?<!\\\\)\"[^\"|^'']\\*(?<!\\\\)\"[^\"|^'']\\*)\\*|[^\"|^'']*))=') {\n                $varAssignment = ($example -split \"=\")[0]\n\n                # for every example we want a single It block\n                It \"Example - $example\" {\n                    # mock the tested command so we don't actually do anything\n                    # because it can be unsafe and we don't have the environment setup\n                    # (so the only thing we are testing is that the code is semantically\n                    # correct and provides all the needed params)\n                    Mock $commandName {\n                        # I am returning true here,\n                        # but some of the examples drill down to the returned object\n                        # so in strict mode we would fail\n                        $true\n                    }\n\n                    $exampleExtended = \"$example;$varAssignment\"\n                    \n                    # here simply invoke the example\n                    $result = Invoke-Expression $exampleExtended\n                    # and check that we got result from the mock\n                    $result | Should -BeTrue\n                }\n            } else {\n                # for every example we want a single It block\n                It \"Example - $example\" {\n                    # mock the tested command so we don't actually do anything\n                    # because it can be unsafe and we don't have the environment setup\n                    # (so the only thing we are testing is that the code is semantically\n                    # correct and provides all the needed params)\n                    Mock $commandName {\n                        # I am returning true here,\n                        # but some of the examples drill down to the returned object\n                        # so in strict mode we would fail\n                        $true\n                    }\n\n                    # here simply invoke the example\n                    $result = Invoke-Expression $example\n                    # and check that we got result from the mock\n                    $result | Should -BeTrue\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/tests/general/Help.Exceptions.ps1",
    "content": "﻿# List of functions that should be ignored\n$global:FunctionHelpTestExceptions = @(\n    'Get-TimeZone'\n)\n\n<#\n  List of arrayed enumerations. These need to be treated differently. Add full name.\n  Example:\n\n  \"Sqlcollaborative.Dbatools.Connection.ManagementConnectionType[]\"\n#>\n$global:HelpTestEnumeratedArrays = @(\n\t\n)\n\n<#\n  Some types on parameters just fail their validation no matter what.\n  For those it becomes possible to skip them, by adding them to this hashtable.\n  Add by following this convention: <command name> = @(<list of parameter names>)\n  Example:\n\n  \"Get-DbaCmObject\"       = @(\"DoNotUse\")\n#>\n$global:HelpTestSkipParameterType = @{\n    \n}\n"
  },
  {
    "path": "d365fo.tools/tests/general/Help.Tests.ps1",
    "content": "﻿<#\n    .NOTES\n        The original test this is based upon was written by June Blender.\n\t\tAfter several rounds of modifications it stands now as it is, but the honor remains hers.\n\n\t\tThank you June, for all you have done!\n\n    .DESCRIPTION\n\t\tThis test evaluates the help for all commands in a module.\n\n\t.PARAMETER SkipTest\n\t\tDisables this test.\n\t\n\t.PARAMETER CommandPath\n\t\tList of paths under which the script files are stored.\n\t\tThis test assumes that all functions have their own file that is named after themselves.\n\t\tThese paths are used to search for commands that should exist and be tested.\n\t\tWill search recursively and accepts wildcards, make sure only functions are found\n\n\t.PARAMETER ModuleName\n\t\tName of the module to be tested.\n\t\tThe module must already be imported\n\n\t.PARAMETER ExceptionsFile\n\t\tFile in which exceptions and adjustments are configured.\n\t\tIn it there should be two arrays and a hashtable defined:\n\t\t\t$global:FunctionHelpTestExceptions\n\t\t\t$global:HelpTestEnumeratedArrays\n\t\t\t$global:HelpTestSkipParameterType\n\t\tThese can be used to tweak the tests slightly in cases of need.\n\t\tSee the example file for explanations on each of these usage and effect.\n#>\n[CmdletBinding()]\nParam (\n\t[switch]\n\t$SkipTest,\n\t\n\t[string[]]\n\t$CommandPath = @(\"$PSScriptRoot\\..\\..\\functions\", \"$PSScriptRoot\\..\\..\\internal\\functions\"),\n\t\n\t[string]\n\t$ModuleName = \"d365fo.tools\",\n\t\n\t[string]\n\t$ExceptionsFile = \"$PSScriptRoot\\Help.Exceptions.ps1\"\n)\nif ($SkipTest) { return }\n. $ExceptionsFile\n\n$includedNames = (Get-ChildItem $CommandPath -Recurse -File | Where-Object Name -like \"*.ps1\").BaseName\n$commands = Get-Command -Module (Get-Module $ModuleName) -CommandType Cmdlet, Function, Workflow | Where-Object Name -in $includedNames\n\n## When testing help, remember that help is cached at the beginning of each session.\n## To test, restart session.\n\n\nforeach ($command in $commands) {\n    $commandName = $command.Name\n    \n    # Skip all functions that are on the exclusions list\n    if ($global:FunctionHelpTestExceptions -contains $commandName) { continue }\n    \n    # The module-qualified command fails on Microsoft.PowerShell.Archive cmdlets\n    $Help = Get-Help $commandName -ErrorAction SilentlyContinue\n    $testhelperrors = 0\n    $testhelpall = 0\n    Describe \"Test help for $commandName\" {\n        \n        $testhelpall += 1\n        if ($Help.Synopsis -like '*`[`<CommonParameters`>`]*') {\n            # If help is not found, synopsis in auto-generated help is the syntax diagram\n            It \"should not be auto-generated\" {\n                $Help.Synopsis | Should -Not -BeLike '*`[`<CommonParameters`>`]*'\n            }\n            $testhelperrors += 1\n        }\n        \n        $testhelpall += 1\n        if ([String]::IsNullOrEmpty($Help.Description.Text)) {\n            # Should be a description for every function\n            It \"gets description for $commandName\" {\n                $Help.Description | Should -Not -BeNullOrEmpty\n            }\n            $testhelperrors += 1\n        }\n        \n        $testhelpall += 1\n        if ([String]::IsNullOrEmpty(($Help.Examples.Example | Select-Object -First 1).Code)) {\n            # Should be at least one example\n            It \"gets example code from $commandName\" {\n                ($Help.Examples.Example | Select-Object -First 1).Code | Should -Not -BeNullOrEmpty\n            }\n            $testhelperrors += 1\n        }\n        \n        $testhelpall += 1\n        if ([String]::IsNullOrEmpty(($Help.Examples.Example.Remarks | Select-Object -First 1).Text)) {\n            # Should be at least one example description\n            It \"gets example help from $commandName\" {\n                ($Help.Examples.Example.Remarks | Select-Object -First 1).Text | Should -Not -BeNullOrEmpty\n            }\n            $testhelperrors += 1\n        }\n        \n        if ($testhelperrors -eq 0) {\n            It \"Ran silently $testhelpall tests\" {\n                $testhelperrors | Should -be 0\n            }\n        }\n        \n        $testparamsall = 0\n        $testparamserrors = 0\n        Context \"Test parameter help for $commandName\" {\n            \n            $Common = 'Debug', 'ErrorAction', 'ErrorVariable', 'InformationAction', 'InformationVariable', 'OutBuffer', 'OutVariable',\n            'PipelineVariable', 'Verbose', 'WarningAction', 'WarningVariable'\n            \n            $parameters = $command.ParameterSets.Parameters | Sort-Object -Property Name -Unique | Where-Object Name -notin $common\n            $parameterNames = $parameters.Name\n            $HelpParameterNames = $Help.Parameters.Parameter.Name | Sort-Object -Unique\n            foreach ($parameter in $parameters) {\n                $parameterName = $parameter.Name\n                $parameterHelp = $Help.parameters.parameter | Where-Object Name -EQ $parameterName\n                \n                $testparamsall += 1\n                if ([String]::IsNullOrEmpty($parameterHelp.Description.Text)) {\n                    # Should be a description for every parameter\n                    It \"gets help for parameter: $parameterName : in $commandName\" {\n                        $parameterHelp.Description.Text | Should -Not -BeNullOrEmpty\n                    }\n                    $testparamserrors += 1\n                }\n                \n                $testparamsall += 1\n                # $codeMandatory = $parameter.IsMandatory.toString()\n                # if ($parameterHelp.Required -ne $codeMandatory) {\n                #     # Required value in Help should match IsMandatory property of parameter\n                #     It \"help for $parameterName parameter in $commandName has correct Mandatory value\" {\n                #         $parameterHelp.Required | Should -Be $codeMandatory\n                #     }\n                #     $testparamserrors += 1\n                # }\n                \n                if ($HelpTestSkipParameterType[$commandName] -contains $parameterName) { continue }\n                \n                $codeType = $parameter.ParameterType.Name\n                \n                $testparamsall += 1\n                if ($parameter.ParameterType.IsEnum) {\n                    # Enumerations often have issues with the typename not being reliably available\n                    $names = $parameter.ParameterType::GetNames($parameter.ParameterType)\n                    if ($parameterHelp.parameterValueGroup.parameterValue -ne $names) {\n                        # Parameter type in Help should match code\n                        It \"help for $commandName has correct parameter type for $parameterName\" {\n                            $parameterHelp.parameterValueGroup.parameterValue | Should -be $names\n                        }\n                        $testparamserrors += 1\n                    }\n                }\n                elseif ($parameter.ParameterType.FullName -in $HelpTestEnumeratedArrays) {\n                    # Enumerations often have issues with the typename not being reliably available\n                    $names = [Enum]::GetNames($parameter.ParameterType.DeclaredMembers[0].ReturnType)\n                    if ($parameterHelp.parameterValueGroup.parameterValue -ne $names) {\n                        # Parameter type in Help should match code\n                        It \"help for $commandName has correct parameter type for $parameterName\" {\n                            $parameterHelp.parameterValueGroup.parameterValue | Should -be $names\n                        }\n                        $testparamserrors += 1\n                    }\n                }\n                else {\n                    # To avoid calling Trim method on a null object.\n                    $helpType = if ($parameterHelp.parameterValue) { $parameterHelp.parameterValue.Trim() }\n                    if ($helpType -ne $codeType) {\n                        # Parameter type in Help should match code\n                        It \"help for $commandName has correct parameter type for $parameterName\" {\n                            $helpType | Should -be $codeType\n                        }\n                        $testparamserrors += 1\n                    }\n                }\n            }\n            foreach ($helpParm in $HelpParameterNames) {\n                $testparamsall += 1\n                if ($helpParm -notin $parameterNames) {\n                    # Shouldn't find extra parameters in help.\n                    It \"finds help parameter in code: $helpParm\" {\n                        $helpParm -in $parameterNames | Should -Be $true\n                    }\n                    $testparamserrors += 1\n                }\n            }\n            if ($testparamserrors -eq 0) {\n                It \"Ran silently $testparamsall tests\" {\n                    $testparamserrors | Should -be 0\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "d365fo.tools/tests/general/Manifest.Tests.ps1",
    "content": "﻿Describe \"Validating the module manifest\" {\n\t$moduleRoot = (Resolve-Path \"$PSScriptRoot\\..\\..\").Path\n\t$manifest = ((Get-Content \"$moduleRoot\\d365fo.tools.psd1\") -join \"`n\") | Invoke-Expression\n\t[version]$moduleVersion = Get-Item \"$moduleRoot\\d365fo.tools.psm1\" | Select-String -Pattern '\\$script:ModuleVersion = \"(.*?)\"' | ForEach-Object { $_.Matches[0].Groups[1].Value }\n\tContext \"Basic resources validation\" {\n\t\t$files = Get-ChildItem \"$moduleRoot\\functions\" -Recurse -File -Filter \"*.ps1\"\n\t\tIt \"Exports all functions in the public folder\" {\n\t\t\t\n\t\t\t$functions = (Compare-Object -ReferenceObject $files.BaseName -DifferenceObject $manifest.FunctionsToExport | Where-Object SideIndicator -Like '<=').InputObject\n\t\t\t$functions | Should -BeNullOrEmpty\n\t\t}\n\t\tIt \"Exports no function that isn't also present in the public folder\" {\n\t\t\t$functions = (Compare-Object -ReferenceObject $files.BaseName -DifferenceObject $manifest.FunctionsToExport | Where-Object SideIndicator -Like '=>').InputObject\n\t\t\t$functions | Should -BeNullOrEmpty\n\t\t}\n\t\t\n\t\tIt \"Exports none of its internal functions\" {\n\t\t\t$files = Get-ChildItem \"$moduleRoot\\internal\\functions\" -Recurse -File -Filter \"*.ps1\"\n\t\t\t$files | Where-Object BaseName -In $manifest.FunctionsToExport | Should -BeNullOrEmpty\n\t\t}\n\t\t\n\t\tIt \"Has the same version as the psm1 file\" {\n\t\t\t([version]$manifest.ModuleVersion) | Should -Be $moduleVersion\n\t\t}\n\t}\n\t\n\tContext \"Individual file validation\" {\n\t\tIt \"The root module file exists\" {\n\t\t\tTest-Path \"$moduleRoot\\$($manifest.RootModule)\" | Should -Be $true\n\t\t}\n\t\t\n\t\tforeach ($format in $manifest.FormatsToProcess)\n\t\t{\n\t\t\tIt \"The file $format should exist\" {\n\t\t\t\tTest-Path \"$moduleRoot\\$format\" | Should -Be $true\n\t\t\t}\n\t\t}\n\t\t\n\t\tforeach ($type in $manifest.TypesToProcess)\n\t\t{\n\t\t\tIt \"The file $type should exist\" {\n\t\t\t\tTest-Path \"$moduleRoot\\$type\" | Should -Be $true\n\t\t\t}\n\t\t}\n\t\t\n\t\tforeach ($assembly in $manifest.RequiredAssemblies)\n\t\t{\n\t\t\tIt \"The file $assembly should exist\" {\n\t\t\t\tTest-Path \"$moduleRoot\\$assembly\" | Should -Be $true\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "d365fo.tools/tests/general/PSScriptAnalyzer.Tests.ps1",
    "content": "﻿[CmdletBinding()]\nParam (\n\t[switch]\n\t$SkipTest,\n\t\n\t[string[]]\n\t$CommandPath = @(\"$PSScriptRoot\\..\\..\\functions\", \"$PSScriptRoot\\..\\..\\internal\\functions\")\n)\n\nif ($SkipTest) { return }\n\n$list = New-Object System.Collections.ArrayList\n\nDescribe 'Invoking PSScriptAnalyzer against commandbase' {\n\t$commandFiles = Get-ChildItem -Path $CommandPath -Recurse -Filter \"*.ps1\"\n\t$scriptAnalyzerRules = Get-ScriptAnalyzerRule\n\t\n\tforeach ($file in $commandFiles)\n\t{\n\t\tContext \"Analyzing $($file.BaseName)\" {\n\t\t\t$analysis = Invoke-ScriptAnalyzer -Path $file.FullName -ExcludeRule PSAvoidTrailingWhitespace, PSShouldProcess, PSReviewUnusedParameter\n\t\t\t\n\t\t\tforEach ($rule in $scriptAnalyzerRules)\n\t\t\t{\n\t\t\t\tIt \"Should pass $rule\" {\n\t\t\t\t\tIf ($analysis.RuleName -contains $rule)\n\t\t\t\t\t{\n\t\t\t\t\t\t$analysis | Where-Object RuleName -EQ $rule -outvariable failures | ForEach-Object { $list.Add($_) }\n\t\t\t\t\t\t\n\t\t\t\t\t\t1 | Should Be 0\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t0 | Should Be 0\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n$list | Out-Default"
  },
  {
    "path": "d365fo.tools/tests/pester-PSScriptAnalyzer.ps1",
    "content": "﻿param (\n\t$TestPublic = $true,\n\t\n\t$TestInternal = $true,\n\t\n\t[ValidateSet('None', 'Default', 'Passed', 'Failed', 'Pending', 'Skipped', 'Inconclusive', 'Describe', 'Context', 'Summary', 'Header', 'Fails', 'All')]\n\t$Show = \"None\",\n\t\n\t$Include = \"*\",\n\t\n\t$Exclude = \"\"\n)\n\nWrite-PSFMessage -Level Important -Message \"Starting Tests\"\n\nWrite-PSFMessage -Level Important -Message \"Importing Module\"\n\nRemove-Module d365fo.tools -ErrorAction Ignore\nImport-Module \"$PSScriptRoot\\..\\d365fo.tools.psd1\"\nImport-Module \"$PSScriptRoot\\..\\d365fo.tools.psm1\" -Force\n\nWrite-PSFMessage -Level Important -Message \"Creating test result folder\"\n$null = New-Item -Path \"$PSScriptRoot\\..\\..\" -Name TestResults -ItemType Directory -Force\n\n$totalFailed = 0\n$totalRun = 0\n\n$testresults = @()\n\n#region Run Public PSScriptAnalyzer Tests\nif ($TestPublic) {\n\tWrite-PSFMessage -Level Important -Message \"Modules imported, proceeding with general tests\"\n\t$file = Get-Item \"$PSScriptRoot\\general\\PSScriptAnalyzer.Tests.ps1\"\n\n\t$pesterParm = @{}\n\t$pesterParm.Path = $file.FullName\n\t$pesterParm.Parameters = @{CommandPath = \"$PSScriptRoot\\..\\functions\" }\n\n\tWrite-PSFMessage -Level Significant -Message \"  Executing <c='em'>$($file.Name)</c>\"\n\t$TestOuputFile = Join-Path \"$PSScriptRoot\\..\\..\\TestResults\" \"TEST-$($file.BaseName).xml\"\n\t$results = Invoke-Pester -Script $pesterParm -Show $Show -PassThru -OutputFile $TestOuputFile -OutputFormat NUnitXml\n\tforeach ($result in $results) {\n\t\t$totalRun += $result.TotalCount\n\t\t$totalFailed += $result.FailedCount\n\t\t$result.TestResult | Where-Object { -not $_.Passed } | ForEach-Object {\n\t\t\t$name = $_.Name\n\t\t\t$testresults += [pscustomobject]@{\n\t\t\t\tDescribe = $_.Describe\n\t\t\t\tContext  = $_.Context\n\t\t\t\tName     = \"It $name\"\n\t\t\t\tResult   = $_.Result\n\t\t\t\tMessage  = $_.FailureMessage\n\t\t\t}\n\t\t}\n\t}\n}\n\n#endregion Run Public PSScriptAnalyzer Tests\n\n#region Run Internal PSScriptAnalyzer Tests\nif ($TestInternal) {\n\tWrite-PSFMessage -Level Important -Message \"Modules imported, proceeding with general tests\"\n\t$file = Get-Item \"$PSScriptRoot\\general\\PSScriptAnalyzer.Tests.ps1\"\n\n\t$pesterParm = @{}\n\t$pesterParm.Path = $file.FullName\n\t$pesterParm.Parameters = @{CommandPath = \"$PSScriptRoot\\..\\internal\\functions\" }\n\n\tWrite-PSFMessage -Level Significant -Message \"  Executing <c='em'>$($file.Name)</c>\"\n\t$TestOuputFile = Join-Path \"$PSScriptRoot\\..\\..\\TestResults\" \"TEST-$($file.BaseName).xml\"\n\t$results = Invoke-Pester -Script $pesterParm -Show $Show -PassThru -OutputFile $TestOuputFile -OutputFormat NUnitXml\n\tforeach ($result in $results) {\n\t\t$totalRun += $result.TotalCount\n\t\t$totalFailed += $result.FailedCount\n\t\t$result.TestResult | Where-Object { -not $_.Passed } | ForEach-Object {\n\t\t\t$name = $_.Name\n\t\t\t$testresults += [pscustomobject]@{\n\t\t\t\tDescribe = $_.Describe\n\t\t\t\tContext  = $_.Context\n\t\t\t\tName     = \"It $name\"\n\t\t\t\tResult   = $_.Result\n\t\t\t\tMessage  = $_.FailureMessage\n\t\t\t}\n\t\t}\n\t}\n}\n#endregion Run Internal PSScriptAnalyzer Tests\n\n$testresults | Sort-Object Describe, Context, Name, Result, Message | Format-List\n\nif ($totalFailed -eq 0) { Write-PSFMessage -Level Critical -Message \"All <c='em'>$totalRun</c> tests executed without a single failure!\" }\nelse { Write-PSFMessage -Level Critical -Message \"<c='em'>$totalFailed tests</c> out of <c='sub'>$totalRun</c> tests failed!\" }\n\nif ($totalFailed -gt 0) {\n\tthrow \"$totalFailed / $totalRun tests failed!\"\n}"
  },
  {
    "path": "d365fo.tools/tests/pester.ps1",
    "content": "﻿param (\n\t$TestGeneral = $true,\n\t\n\t$TestFunctions = $true,\n\t\n\t[ValidateSet('None', 'Default', 'Passed', 'Failed', 'Pending', 'Skipped', 'Inconclusive', 'Describe', 'Context', 'Summary', 'Header', 'Fails', 'All')]\n\t$Show = \"None\",\n\t\n\t$Include = \"*\",\n\t\n\t$Exclude = \"\"\n)\n\nWrite-PSFMessage -Level Important -Message \"Starting Tests\"\n\nWrite-PSFMessage -Level Important -Message \"Importing Module\"\n\nRemove-Module d365fo.tools -ErrorAction Ignore\nImport-Module \"$PSScriptRoot\\..\\d365fo.tools.psd1\"\nImport-Module \"$PSScriptRoot\\..\\d365fo.tools.psm1\" -Force\n\nWrite-PSFMessage -Level Important -Message \"Creating test result folder\"\n$null = New-Item -Path \"$PSScriptRoot\\..\\..\" -Name TestResults -ItemType Directory -Force\n\n$totalFailed = 0\n$totalRun = 0\n\n$testresults = @()\n\n#region Run General Tests\nif ($TestGeneral) {\n\tWrite-PSFMessage -Level Important -Message \"Modules imported, proceeding with general tests\"\n\tforeach ($file in (Get-ChildItem \"$PSScriptRoot\\general\" -Filter \"*.Tests.ps1\")) {\n\t\n\t\tif ($file.Name -notlike $Include) { continue }\n\t\tif ($file.Name -like $Exclude) { continue }\n\n\t\tWrite-PSFMessage -Level Significant -Message \"  Executing <c='em'>$($file.Name)</c>\"\n\t\t$TestOuputFile = Join-Path \"$PSScriptRoot\\..\\..\\TestResults\" \"TEST-$($file.BaseName).xml\"\n\t\t$results = Invoke-Pester -Script $file.FullName -Show $Show -PassThru -OutputFile $TestOuputFile -OutputFormat NUnitXml\n\t\tforeach ($result in $results) {\n\t\t\t$totalRun += $result.TotalCount\n\t\t\t$totalFailed += $result.FailedCount\n\t\t\t$result.TestResult | Where-Object { -not $_.Passed } | ForEach-Object {\n\t\t\t\t$name = $_.Name\n\t\t\t\t$testresults += [pscustomobject]@{\n\t\t\t\t\tDescribe = $_.Describe\n\t\t\t\t\tContext  = $_.Context\n\t\t\t\t\tName     = \"It $name\"\n\t\t\t\t\tResult   = $_.Result\n\t\t\t\t\tMessage  = $_.FailureMessage\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n#endregion Run General Tests\n\n#region Test Commands\nif ($TestFunctions) {\n\tWrite-PSFMessage -Level Important -Message \"Proceeding with individual tests\"\n\tforeach ($file in (Get-ChildItem \"$PSScriptRoot\\functions\" -Recurse -File -Filter \"*Tests.ps1\")) {\n\t\n\t\tif ($file.Name -notlike $Include) { continue }\n\t\tif ($file.Name -like $Exclude) { continue }\n\t\n\t\tWrite-PSFMessage -Level Significant -Message \"  Executing $($file.Name)\"\n\t\t$TestOuputFile = Join-Path \"$PSScriptRoot\\..\\..\\TestResults\" \"TEST-$($file.BaseName).xml\"\n\t\t$results = Invoke-Pester -Script $file.FullName -Show $Show -PassThru -OutputFile $TestOuputFile -OutputFormat NUnitXml\n\t\tforeach ($result in $results) {\n\t\t\t$totalRun += $result.TotalCount\n\t\t\t$totalFailed += $result.FailedCount\n\t\t\t$result.TestResult | Where-Object { -not $_.Passed } | ForEach-Object {\n\t\t\t\t$name = $_.Name\n\t\t\t\t$testresults += [pscustomobject]@{\n\t\t\t\t\tDescribe = $_.Describe\n\t\t\t\t\tContext  = $_.Context\n\t\t\t\t\tName     = \"It $name\"\n\t\t\t\t\tResult   = $_.Result\n\t\t\t\t\tMessage  = $_.FailureMessage\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n#endregion Test Commands\n\n$testresults | Sort-Object Describe, Context, Name, Result, Message | Format-List\n\nif ($totalFailed -eq 0) { Write-PSFMessage -Level Critical -Message \"All <c='em'>$totalRun</c> tests executed without a single failure!\" }\nelse { Write-PSFMessage -Level Critical -Message \"<c='em'>$totalFailed tests</c> out of <c='sub'>$totalRun</c> tests failed!\" }\n\nif ($totalFailed -gt 0) {\n\tthrow \"$totalFailed / $totalRun tests failed!\"\n}"
  },
  {
    "path": "d365fo.tools/tests/readme.md",
    "content": "﻿# Description\n\nThis is the folder, where all the tests go.\n\nThose are subdivided in two categories:\n\n - General\n - Function\n\n## General Tests\n\nGeneral tests are function generic and test for general policies.\n\nThese test scan answer questions such as:\n\n - Is my module following my style guides?\n - Does any of my scripts have a syntax error?\n - Do my scripts use commands I do not want them to use?\n - Do my commands follow best practices?\n - Do my commands have proper help?\n\nBasically, these allow a general module health check.\n\nThese tests are already provided as part of the template.\n\n## Function Tests\n\nA healthy module should provide unit and integration tests for the commands & components it ships.\nOnly then can be guaranteed, that they will actually perform as promised.\n\nHowever, as each such test must be specific to the function it tests, there cannot be much in the way of templates."
  },
  {
    "path": "d365fo.tools/xml/d365fo.tools.Format.ps1xml",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<Configuration>\n\t<ViewDefinitions>\n\t\t<!-- Foo.Bar -->\n\t\t<View>\n\t\t\t<Name>Foo.Bar</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>Foo.Bar</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<TableControl>\n\t\t\t\t<AutoSize/>\n\t\t\t\t<TableHeaders>\n\t\t\t\t\t<TableColumnHeader/>\n\t\t\t\t\t<TableColumnHeader/>\n\t\t\t\t</TableHeaders>\n\t\t\t\t<TableRowEntries>\n\t\t\t\t\t<TableRowEntry>\n\t\t\t\t\t\t<TableColumnItems>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Foo</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Bar</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t</TableColumnItems>\n\t\t\t\t\t</TableRowEntry>\n\t\t\t\t</TableRowEntries>\n\t\t\t</TableControl>\n\t\t</View>\n\t\t<View>\n\t\t\t<Name>D365FO.TOOLS.Label</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>D365FO.TOOLS.Label</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<TableControl>\n\t\t\t\t<TableHeaders>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>20</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>80</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>8</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t</TableHeaders>\n\t\t\t\t<TableRowEntries>\n\t\t\t\t\t<TableRowEntry>\n\t\t\t\t\t\t<TableColumnItems>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Name</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Value</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Language</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t</TableColumnItems>\n\t\t\t\t\t</TableRowEntry>\n\t\t\t\t</TableRowEntries>\n\t\t\t</TableControl>\n\t\t</View>\n\t\t<View>\n\t\t\t<Name>D365FO.TOOLS.ModuleCompileOutput</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>D365FO.TOOLS.ModuleCompileOutput</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<ListControl>\n\t\t\t\t<ListEntries>\n\t\t\t\t\t<ListEntry>\n\t\t\t\t\t\t<ListItems>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>LogFile</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>XmlLogFile</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t</ListItems>\n\t\t\t\t\t</ListEntry>\n\t\t\t\t</ListEntries>\n\t\t\t</ListControl>\n\t\t</View>\n\t\t<View>\n\t\t\t<Name>D365FO.TOOLS.ModuleReportsCompileOutput</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>D365FO.TOOLS.ModuleReportsCompileOutput</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<ListControl>\n\t\t\t\t<ListEntries>\n\t\t\t\t\t<ListEntry>\n\t\t\t\t\t\t<ListItems>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>LogFile</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>XmlLogFile</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t</ListItems>\n\t\t\t\t\t</ListEntry>\n\t\t\t\t</ListEntries>\n\t\t\t</ListControl>\n\t\t</View>\n\t\t<View>\n\t\t\t<Name>D365FO.TOOLS.AZCOPYTRANSFER</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>D365FO.TOOLS.AZCOPYTRANSFER</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<ListControl>\n\t\t\t\t<ListEntries>\n\t\t\t\t\t<ListEntry>\n\t\t\t\t\t\t<ListItems>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>FileName</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>File</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>SourceUri</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t</ListItems>\n\t\t\t\t\t</ListEntry>\n\t\t\t\t</ListEntries>\n\t\t\t</ListControl>\n\t\t</View>\n\t\t<View>\n\t\t\t<Name>D365FO.TOOLS.ModuleLabelGenerationOutput</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>D365FO.TOOLS.ModuleLabelGenerationOutput</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<ListControl>\n\t\t\t\t<ListEntries>\n\t\t\t\t\t<ListEntry>\n\t\t\t\t\t\t<ListItems>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>OutLogFile</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>ErrorLogFile</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t</ListItems>\n\t\t\t\t\t</ListEntry>\n\t\t\t\t</ListEntries>\n\t\t\t</ListControl>\n\t\t</View>\n\t\t<View>\n\t\t\t<Name>D365FO.TOOLS.Azure.Blob</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>D365FO.TOOLS.Azure.Blob</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<TableControl>\n\t\t\t\t<TableHeaders>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>70</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>12</Width>\n\t\t\t\t\t\t<Alignment>Right</Alignment>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>30</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t</TableHeaders>\n\t\t\t\t<TableRowEntries>\n\t\t\t\t\t<TableRowEntry>\n\t\t\t\t\t\t<TableColumnItems>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Name</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Size</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>LastModified</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t</TableColumnItems>\n\t\t\t\t\t</TableRowEntry>\n\t\t\t\t</TableRowEntries>\n\t\t\t</TableControl>\n\t\t</View>\n\t\t<View>\n\t\t\t<Name>D365FO.TOOLS.Environment.Service</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>D365FO.TOOLS.Environment.Service</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<TableControl>\n\t\t\t\t<TableHeaders>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>18</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>60</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>10</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>10</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>22</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t</TableHeaders>\n\t\t\t\t<TableRowEntries>\n\t\t\t\t\t<TableRowEntry>\n\t\t\t\t\t\t<TableColumnItems>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Server</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>DisplayName</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Status</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>StartType</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Name</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t</TableColumnItems>\n\t\t\t\t\t</TableRowEntry>\n\t\t\t\t</TableRowEntries>\n\t\t\t</TableControl>\n\t\t</View>\n\t\t<View>\n\t\t\t<Name>D365FO.TOOLS.Environment.Service.Minimal</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>D365FO.TOOLS.Environment.Service.Minimal</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<TableControl>\n\t\t\t\t<TableHeaders>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>70</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>10</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>10</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>30</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t</TableHeaders>\n\t\t\t\t<TableRowEntries>\n\t\t\t\t\t<TableRowEntry>\n\t\t\t\t\t\t<TableColumnItems>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>DisplayName</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Status</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>StartType</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Name</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t</TableColumnItems>\n\t\t\t\t\t</TableRowEntry>\n\t\t\t\t</TableRowEntries>\n\t\t\t</TableControl>\n\t\t</View>\n\t\t<View>\n\t\t\t<Name>D365FO.TOOLS.LCS.Environment.Operation.Status</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>D365FO.TOOLS.LCS.Environment.Operation.Status</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<ListControl>\n\t\t\t\t<ListEntries>\n\t\t\t\t\t<ListEntry>\n\t\t\t\t\t\t<ListItems>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>ActivityId</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>IsSuccess</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>OperationActivityId</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>ProjectId</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>EnvironmentId</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>ErrorMessage</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>VersionEOL</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t</ListItems>\n\t\t\t\t\t</ListEntry>\n\t\t\t\t</ListEntries>\n\t\t\t</ListControl>\n\t\t</View>\n\t\t<View>\n\t\t\t<Name>D365FO.TOOLS.LCS.Database.Operation.Status</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>D365FO.TOOLS.LCS.Database.Operation.Status</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<ListControl>\n\t\t\t\t<ListEntries>\n\t\t\t\t\t<ListEntry>\n\t\t\t\t\t\t<ListItems>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>ActivityId</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>IsSuccess</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>OperationStatus</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>CompletionDate</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>OperationActivityId</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>ProjectId</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>EnvironmentId</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>ErrorMessage</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>VersionEOL</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t</ListItems>\n\t\t\t\t\t</ListEntry>\n\t\t\t\t</ListEntries>\n\t\t\t</ListControl>\n\t\t</View>\n\t\t<View>\n\t\t\t<Name>D365FO.TOOLS.LCS.Deployment.Operation.Status</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>D365FO.TOOLS.LCS.Deployment.Operation.Status</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<ListControl>\n\t\t\t\t<ListEntries>\n\t\t\t\t\t<ListEntry>\n\t\t\t\t\t\t<ListItems>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>ActivityId</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>IsSuccess</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>OperationStatus</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>CompletionDate</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>OperationActivityId</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>ProjectId</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>EnvironmentId</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>ErrorMessage</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>VersionEOL</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t</ListItems>\n\t\t\t\t\t</ListEntry>\n\t\t\t\t</ListEntries>\n\t\t\t</ListControl>\n\t\t</View>\n\t\t<View>\n\t\t\t<Name>D365FO.TOOLS.ModelInfo</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>D365FO.TOOLS.ModelInfo</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<TableControl>\n\t\t\t\t<TableHeaders>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>30</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>30</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>8</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>13</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>9</Width>\n\t\t\t\t\t\t<Alignment>Right</Alignment>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Alignment>Left</Alignment>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t</TableHeaders>\n\t\t\t\t<TableRowEntries>\n\t\t\t\t\t<TableRowEntry>\n\t\t\t\t\t\t<TableColumnItems>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>ModelName</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Module</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>IsBinary</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Customization</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Id</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Publisher</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t</TableColumnItems>\n\t\t\t\t\t</TableRowEntry>\n\t\t\t\t</TableRowEntries>\n\t\t\t</TableControl>\n\t\t</View>\n\t\t<View>\n\t\t\t<Name>D365FO.TOOLS.CompilerOutput</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>D365FO.TOOLS.CompilerOutput</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<TableControl>\n\t\t\t\t<TableHeaders>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Alignment>Left</Alignment>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>9</Width>\n\t\t\t\t\t\t<Alignment>Right</Alignment>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>9</Width>\n\t\t\t\t\t\t<Alignment>Right</Alignment>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t</TableHeaders>\n\t\t\t\t<TableRowEntries>\n\t\t\t\t\t<TableRowEntry>\n\t\t\t\t\t\t<TableColumnItems>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>File</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Warnings</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Errors</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t</TableColumnItems>\n\t\t\t\t\t</TableRowEntry>\n\t\t\t\t</TableRowEntries>\n\t\t\t</TableControl>\n\t\t</View>\n\t\t<View>\n\t\t\t<Name>D365FO.TOOLS.ModuleInfo</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>D365FO.TOOLS.ModuleInfo</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<TableControl>\n\t\t\t\t<TableHeaders>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>40</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>8</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>15</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Alignment>Left</Alignment>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t</TableHeaders>\n\t\t\t\t<TableRowEntries>\n\t\t\t\t\t<TableRowEntry>\n\t\t\t\t\t\t<TableColumnItems>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>ModuleName</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>IsBinary</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Version</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>References</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t</TableColumnItems>\n\t\t\t\t\t</TableRowEntry>\n\t\t\t\t</TableRowEntries>\n\t\t\t</TableControl>\n\t\t</View>\n\t\t<View>\n\t\t\t<Name>D365FO.TOOLS.FileObject</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>D365FO.TOOLS.FileObject</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<ListControl>\n\t\t\t\t<ListEntries>\n\t\t\t\t\t<ListEntry>\n\t\t\t\t\t\t<ListItems>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>Filename</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>LastModified</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t\t<ListItem>\n\t\t\t\t\t\t\t\t<PropertyName>File</PropertyName>\n\t\t\t\t\t\t\t</ListItem>\n\t\t\t\t\t\t</ListItems>\n\t\t\t\t\t</ListEntry>\n\t\t\t\t</ListEntries>\n\t\t\t</ListControl>\n\t\t</View>\n\t\t<View>\n\t\t\t<Name>D365FO.TOOLS.Bacpac.Table</Name>\n\t\t\t<ViewSelectedBy>\n\t\t\t\t<TypeName>D365FO.TOOLS.Bacpac.Table</TypeName>\n\t\t\t</ViewSelectedBy>\n\t\t\t<TableControl>\n\t\t\t\t<TableHeaders>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>70</Width>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>12</Width>\n\t\t\t\t\t\t<Alignment>Right</Alignment>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>14</Width>\n\t\t\t\t\t\t<Alignment>Right</Alignment>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t\t<TableColumnHeader>\n\t\t\t\t\t\t<Width>9</Width>\n\t\t\t\t\t\t<Alignment>Right</Alignment>\n\t\t\t\t\t</TableColumnHeader>\n\t\t\t\t</TableHeaders>\n\t\t\t\t<TableRowEntries>\n\t\t\t\t\t<TableRowEntry>\n\t\t\t\t\t\t<TableColumnItems>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>Name</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>OriginalSize</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>CompressedSize</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t\t<TableColumnItem>\n\t\t\t\t\t\t\t\t<PropertyName>BulkFiles</PropertyName>\n\t\t\t\t\t\t\t</TableColumnItem>\n\t\t\t\t\t\t</TableColumnItems>\n\t\t\t\t\t</TableRowEntry>\n\t\t\t\t</TableRowEntries>\n\t\t\t</TableControl>\n\t\t</View>\n\t</ViewDefinitions>\n</Configuration>"
  },
  {
    "path": "d365fo.tools/xml/d365fo.tools.Types.ps1xml",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Types>\n  <!-- Foo.Bar -->\n  <Type>\n    <Name>Deserialized.Foo.Bar</Name>\n    <Members>\n      <MemberSet>\n        <Name>PSStandardMembers</Name>\n        <Members>\n          <NoteProperty>\n            <Name>\n              TargetTypeForDeserialization\n            </Name>\n            <Value>\n              Foo.Bar\n            </Value>\n          </NoteProperty>\n        </Members>\n      </MemberSet>\n    </Members>\n  </Type>\n  <Type>\n    <Name>Foo.Bar</Name>\n    <Members>\n      <CodeProperty IsHidden=\"true\">\n        <Name>SerializationData</Name>\n        <GetCodeReference>\n          <TypeName>PSFramework.Serialization.SerializationTypeConverter</TypeName>\n          <MethodName>GetSerializationData</MethodName>\n        </GetCodeReference>\n      </CodeProperty>\n    </Members>\n    <TypeConverter>\n      <TypeName>PSFramework.Serialization.SerializationTypeConverter</TypeName>\n    </TypeConverter>\n  </Type>\n</Types>"
  },
  {
    "path": "d365fo.tools/xml/readme.md",
    "content": "﻿# XML\n\nThis is the folder where project XML files go, notably:\n\n - Format XML\n - Type Extension XML\n\nExternal help files should _not_ be placed in this folder!\n\n## Notes on Files and Naming\n\nThere should be only one format file and one type extension file per project, as importing them has a notable impact on import times.\n\n - The Format XML should be named `d365fo.tools.Format.ps1xml`\n - The Type Extension XML should be named `d365fo.tools.Types.ps1xml`\n\n## Tools\n\n### New-PSMDFormatTableDefinition\n\nThis function will take an input object and generate format xml for an auto-sized table.\n\nIt provides a simple way to get started with formats.\n\n### Get-PSFTypeSerializationData\n\n```\nC# Warning!\nThis section is only interest if you're using C# together with PowerShell.\n```\n\nThis function generates type extension XML that allows PowerShell to convert types written in C# to be written to file and restored from it without being 'Deserialized'. Also works for jobs or remoting, if both sides have the `PSFramework` module and type extension loaded.\n\nIn order for a class to be eligible for this, it needs to conform to the following rules:\n\n - Have the `[Serializable]` attribute\n - Be public\n - Have an empty constructor\n - Allow all public properties/fields to be set (even if setting it doesn't do anything) without throwing an exception.\n\n```\nnon-public properties and fields will be lost in this process!\n```"
  },
  {
    "path": "docs/Add-D365AzureStorageConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Add-D365AzureStorageConfig\n\n## SYNOPSIS\nSave an Azure Storage Account config\n\n## SYNTAX\n\n### AccessToken\n```\nAdd-D365AzureStorageConfig -Name <String> -AccountId <String> -AccessToken <String> -Container <String>\n [-Temporary] [-Force] [<CommonParameters>]\n```\n\n### SAS\n```\nAdd-D365AzureStorageConfig -Name <String> -AccountId <String> -SAS <String> -Container <String> [-Temporary]\n [-Force] [<CommonParameters>]\n```\n\n## DESCRIPTION\nAdds an Azure Storage Account config to the configuration store\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nAdd-D365AzureStorageConfig -Name \"UAT-Exports\" -AccountId \"1234\" -AccessToken \"dafdfasdfasdf\" -Container \"testblob\"\n```\n\nThis will add an entry into the list of Azure Storage Accounts that is stored with the name \"UAT-Exports\" with AccountId \"1234\", AccessToken \"dafdfasdfasdf\" and blob container \"testblob\".\n\n### EXAMPLE 2\n```\nAdd-D365AzureStorageConfig -Name UAT-Exports -SAS \"sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" -AccountId \"1234\" -Container \"testblob\"\n```\n\nThis will add an entry into the list of Azure Storage Accounts that is stored with the name \"UAT-Exports\" with AccountId \"1234\", SAS \"sv=2018-03-28&si=unlisted&sr=c&sig=AUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" and blob container \"testblob\".\nThe SAS key enables you to provide explicit access to a given blob container inside an Azure Storage Account.\nThe SAS key can easily be revoked and that way you have control over the access to the container and its content.\n\n### EXAMPLE 3\n```\nAdd-D365AzureStorageConfig -Name UAT-Exports -SAS \"sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" -AccountId \"1234\" -Container \"testblob\" -Temporary\n```\n\nThis will add an entry into the list of Azure Storage Accounts that is stored with the name \"UAT-Exports\" with AccountId \"1234\", SAS \"sv=2018-03-28&si=unlisted&sr=c&sig=AUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" and blob container \"testblob\".\nThe SAS key enables you to provide explicit access to a given blob container inside an Azure Storage Account.\nThe SAS key can easily be revoked and that way you have control over the access to the container and its content.\n\nThe configuration will only last for the rest of this PowerShell console session.\n\n## PARAMETERS\n\n### -Name\nThe logical name of the Azure Storage Account you are about to registered in the configuration store\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AccountId\nThe account id for the Azure Storage Account you want to register in the configuration store\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AccessToken\nThe access token for the Azure Storage Account you want to register in the configuration store\n\n```yaml\nType: String\nParameter Sets: AccessToken\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SAS\nThe SAS key that you have created for the storage account or blob container\n\n```yaml\nType: String\nParameter Sets: SAS\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Container\nThe name of the blob container inside the Azure Storage Account you want to register in the configuration store\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Blobname, Blob\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Temporary\nInstruct the cmdlet to only temporarily add the azure storage account configuration in the configuration store\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nSwitch to instruct the cmdlet to overwrite already registered Azure Storage Account entry\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Azure, Azure Storage, Config, Configuration, Token, Blob, Container\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Add-D365BroadcastMessageConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Add-D365BroadcastMessageConfig\n\n## SYNOPSIS\nSave a broadcast message config\n\n## SYNTAX\n\n```\nAdd-D365BroadcastMessageConfig [-Name] <String> [[-Tenant] <String>] [[-URL] <String>] [[-ClientId] <String>]\n [[-ClientSecret] <String>] [[-TimeZone] <String>] [[-EndingInMinutes] <Int32>] [-OnPremise] [-Temporary]\n [-Force] [<CommonParameters>]\n```\n\n## DESCRIPTION\nAdds a broadcast message config to the configuration store\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nAdd-D365BroadcastMessageConfig -Name \"UAT\" -Tenant \"e674da86-7ee5-40a7-b777-1111111111111\" -URL \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" -ClientId \"dea8d7a9-1602-4429-b138-111111111111\" -ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\"\n```\n\nThis will create a new broadcast message configuration with the name \"UAT\".\nIt will save \"e674da86-7ee5-40a7-b777-1111111111111\" as the Azure Active Directory guid.\nIt will save \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" as the D365FO environment.\nIt will save \"dea8d7a9-1602-4429-b138-111111111111\" as the ClientId.\nIt will save \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\" as ClientSecret.\nIt will use the default value \"UTC\" Time Zone for converting the different time and dates.\nIt will use the default end time which is 60 minutes.\n\n### EXAMPLE 2\n```\nAdd-D365BroadcastMessageConfig -Name \"UAT\" -OnPremise -Tenant \"https://adfs.local/adfs\" -URL \"https://ax-sandbox.d365fo.local\" -ClientId \"dea8d7a9-1602-4429-b138-111111111111\" -ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\"\n```\n\nThis will create a new broadcast message configuration with the name \"UAT\".\nIt will target an OnPremise environment.\nIt will save \"https://adfs.local/adfs\" as the OAuth Tenant Provider.\nIt will save \"https://ax-sandbox.d365fo.local\" as the D365FO environment.\nIt will save \"dea8d7a9-1602-4429-b138-111111111111\" as the ClientId.\nIt will save \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\" as ClientSecret.\nIt will use the default value \"UTC\" Time Zone for converting the different time and dates.\nIt will use the default end time which is 60 minutes.\n\n## PARAMETERS\n\n### -Name\nThe logical name of the broadcast configuration you are about to register in the configuration store\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Tenant\nAzure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to send a message to\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: $AADGuid\n\nRequired: False\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -URL\nURL / URI for the D365FO environment you want to send a message to\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: URI\n\nRequired: False\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ClientId\nThe ClientId obtained from the Azure Portal when you created a Registered Application\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ClientSecret\nThe ClientSecret obtained from the Azure Portal when you created a Registered Application\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -TimeZone\nId of the Time Zone your environment is running in\n\nYou might experience that the local VM running the D365FO is running another Time Zone than the computer you are running this cmdlet from\n\nAll available .NET Time Zones can be traversed with tab for this parameter\n\nThe default value is \"UTC\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: UTC\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EndingInMinutes\nSpecify how many minutes into the future you want this message / maintenance window to last\n\nDefault value is 60 minutes\n\nThe specified StartTime will always be based on local Time Zone.\nIf you specify a different Time Zone than the local computer is running, the start and end time will be calculated based on your selection.\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: 60\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OnPremise\nSpecify if environnement is an D365 OnPremise\n\nDefault value is \"Not set\" (= Cloud Environnement)\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Temporary\nInstruct the cmdlet to only temporarily add the broadcast message configuration in the configuration store\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nInstruct the cmdlet to overwrite the broadcast message configuration with the same name\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Servicing, Broadcast, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Clear-D365ActiveBroadcastMessageConfig]()\n\n[Get-D365ActiveBroadcastMessageConfig]()\n\n[Get-D365BroadcastMessageConfig]()\n\n[Remove-D365BroadcastMessageConfig]()\n\n[Send-D365BroadcastMessage]()\n\n[Set-D365ActiveBroadcastMessageConfig]()\n\n"
  },
  {
    "path": "docs/Add-D365ModuleToRemove.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Add-D365ModuleToRemove\n\n## SYNOPSIS\nAdds a ModuleToRemove.txt file to a deployable package\n\n## SYNTAX\n\n```\nAdd-D365ModuleToRemove [-ModuleToRemove] <String> [-DeployablePackage] <String> [-OutputPath <String>]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nModifies an existing deployable package and adds a ModuleToRemove.txt file to it.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nAdd-D365ModuleToRemove -ModuleToRemove \"C:\\temp\\ModuleToRemove.txt\" -DeployablePackage \"C:\\temp\\DeployablePackage.zip\"\n```\n\nThis will take the \"C:\\temp\\ModuleToRemove.txt\" file and add it to the \"C:\\temp\\DeployablePackage.zip\" deployable package in the \"AOSService/Scripts\" folder.\n\n### EXAMPLE 2\n```\nNew-D365ModuleToRemove -Path C:\\Temp -Modules \"MyRemovedModule1\",\"MySecondRemovedModule\" | Add-D365ModuleToRemove -DeployablePackage C:\\Temp\\DeployablePackage.zip\n```\n\nThis will create a new ModuleToRemove.txt file and fill in \"MyRemovedModule1\" and \"MySecondRemovedModule\" as the modules to remove.\nThe file is then added to the \"C:\\Temp\\DeployablePackage.zip\" deployable package.\n\n## PARAMETERS\n\n### -ModuleToRemove\nPath to the ModuleToRemove.txt file that you want to have inside a deployable package\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -DeployablePackage\nPath to the deployable package file where the ModuleToRemove.txt file should be added\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputPath\nPath where you want the generated deployable package to be stored\n\nDefault value is the same as the \"DeployablePackage\" parameter\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $DeployablePackage\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Florian Hopfner (@FH-Inway)\n\n## RELATED LINKS\n\n[New-D365ModuleToRemove]()\n\n"
  },
  {
    "path": "docs/Add-D365RsatWifConfigAuthorityThumbprint.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Add-D365RsatWifConfigAuthorityThumbprint\n\n## SYNOPSIS\nAdd a certificate thumbprint to the wif.config.\n\n## SYNTAX\n\n```\nAdd-D365RsatWifConfigAuthorityThumbprint [-CertificateThumbprint] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\nRegister a certificate thumbprint in the wif.config file.\nThis can be useful for example when configuring RSAT on a local machine and add the used certificate thumbprint to that AOS.s\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nAdd-D365RsatWifConfigAuthorityThumbprint -CertificateThumbprint \"12312323r424\"\n```\n\nThis will open the wif.config file and insert the \"12312323r424\" thumbprint value into the file.\n\n## PARAMETERS\n\n### -CertificateThumbprint\nThe thumbprint value of the certificate that you want to register in the wif.config file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: RSAT, Certificate, Testing, Regression Suite Automation Test, Regression, Test, Automation\n\nAuthor: Kenny Saelen (@kennysaelen)\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Add-D365WindowsDefenderRules.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Add-D365WindowsDefenderRules\n\n## SYNOPSIS\nAdd rules to Windows Defender to enhance performance during development.\n\n## SYNTAX\n\n```\nAdd-D365WindowsDefenderRules [-Silent] [<CommonParameters>]\n```\n\n## DESCRIPTION\nAdd rules to the Windows Defender to exclude Visual Studio, D365 Batch process, D365 Sync process, XPP related processes and SQL Server processes from scans and monitoring.\nThis will lead to performance gains because the Windows Defender stops to scan every file accessed by e.g.\nthe MSBuild process, the cache and things around Visual Studio.\nSupports rules for VS 2015 and VS 2019.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nAdd-D365WindowsDefenderRules\n```\n\nThis will add the most common rules to the Windows Defender as exceptions.\nAll output will be written to the console.\n\n### EXAMPLE 2\n```\nAdd-D365WindowsDefenderRules -Silent\n```\n\nThis will add the most common rules to the Windows Defender as exceptions.\nAll output will be silenced and not outputted to the console.\n\n## PARAMETERS\n\n### -Silent\nInstruct the cmdlet to silence the output written to the console\n\nIf set the output will be silenced, if not set, the output will be written to the console\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: DevTools, Developer, Performance\n\nAuthor: Robin Kretzschmar (@darksmile92)\n\nAuthor: Mötz Jensen (@Splaxi)\n\nAuthor: Florian Hopfner (@FH-Inway)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Backup-D365DevConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Backup-D365DevConfig\n\n## SYNOPSIS\nBackup the DynamicsDevConfig.xml file\n\n## SYNTAX\n\n```\nBackup-D365DevConfig [[-OutputPath] <String>] [-Force] [<CommonParameters>]\n```\n\n## DESCRIPTION\nWill backup the DynamicsDevConfig.xml file located in the PackagesLocalDirectory\\Bin folder\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nBackup-D365DevConfig\n```\n\nWill locate the DynamicsDevConfig.xml file, and back it up.\nIt will look for the file in the PackagesLocalDirectory\\Bin folder.\nE.g.\nK:\\AosService\\PackagesLocalDirectory\\Bin\\DynamicsDevConfig.xml.\nIt will save the file to the default location: \"C:\\Temp\\d365fo.tools\\DevConfigBackup\".\n\nA result set example:\n\nFilename              LastModified         File\n--------              ------------         ----\nDynamicsDevConfig.xml 6/29/2021 7:31:04 PM C:\\temp\\d365fo.tools\\DevConfigBackup\\DynamicsDevConfig.xml\n\n### EXAMPLE 2\n```\nBackup-D365DevConfig -Force\n```\n\nWill locate the DynamicsDevConfig.xml file, back it up, and overwrite if a previous backup file exists.\nIt will look for the file in the PackagesLocalDirectory\\Bin folder.\nE.g.\nK:\\AosService\\PackagesLocalDirectory\\Bin\\DynamicsDevConfig.xml.\nIt will save the file to the default location: \"C:\\Temp\\d365fo.tools\\DevConfigBackup\".\nIt will overwrite any file named DynamicsDevConfig.xml in the destination folder.\n\nA result set example:\n\nFilename              LastModified         File\n--------              ------------         ----\nDynamicsDevConfig.xml 6/29/2021 7:31:04 PM C:\\temp\\d365fo.tools\\DevConfigBackup\\DynamicsDevConfig.xml\n\n## PARAMETERS\n\n### -OutputPath\nPath to the folder where you want the DynamicsDevConfig.xml file to be persisted\n\nDefault is: \"C:\\Temp\\d365fo.tools\\DevConfigBackup\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $(Join-Path $Script:DefaultTempPath \"DevConfigBackup\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nInstructs the cmdlet to overwrite the destination file if it already exists\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Web Server, IIS, IIS Express, Development\n\nAuthor: Sander Holvoet (@smholvoet)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Backup-D365MetaDataDir.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Backup-D365MetaDataDir\n\n## SYNOPSIS\nCreate a backup of the Metadata directory\n\n## SYNTAX\n\n```\nBackup-D365MetaDataDir [[-MetaDataDir] <String>] [[-BackupDir] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nCreates a backup of all the files and folders from the Metadata directory\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nBackup-D365MetaDataDir\n```\n\nThis will backup the PackagesLocalDirectory and create an PackagesLocalDirectory_backup next to it\n\n## PARAMETERS\n\n### -MetaDataDir\nPath to the Metadata directory\n\nDefault value is the PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:MetaDataDir\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BackupDir\nPath where you want the backup to be place\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$($Script:MetaDataDir)_backup\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: PackagesLocalDirectory, MetaData, MetaDataDir, MeteDataDirectory, Backup, Development\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Backup-D365Runbook.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Backup-D365Runbook\n\n## SYNOPSIS\nBackup a runbook file\n\n## SYNTAX\n\n```\nBackup-D365Runbook [-File] <String> [[-DestinationPath] <String>] [-Force] [<CommonParameters>]\n```\n\n## DESCRIPTION\nBackup a runbook file for you to persist it for later analysis\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nBackup-D365Runbook -File \"C:\\DynamicsAX\\InstallationRecords\\Runbooks\\Runbook_20190327.xml\"\n```\n\nThis will backup the \"C:\\DynamicsAX\\InstallationRecords\\Runbooks\\Runbook_20190327.xml\".\nThe default destination folder is used, \"c:\\temp\\d365fo.tools\\runbookbackups\\\".\n\n### EXAMPLE 2\n```\nBackup-D365Runbook -File \"C:\\DynamicsAX\\InstallationRecords\\Runbooks\\Runbook_20190327.xml\" -Force\n```\n\nThis will backup the \"C:\\DynamicsAX\\InstallationRecords\\Runbooks\\Runbook_20190327.xml\".\nThe default destination folder is used, \"c:\\temp\\d365fo.tools\\runbookbackups\\\".\nIf the file already exists in the destination folder, it will be overwritten.\n\n### EXAMPLE 3\n```\nGet-D365Runbook | Backup-D365Runbook\n```\n\nThis will backup all runbook files found with the \"Get-D365Runbook\" cmdlet.\nThe default destination folder is used, \"c:\\temp\\d365fo.tools\\runbookbackups\\\".\n\n## PARAMETERS\n\n### -File\nPath to the file you want to backup\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Path\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -DestinationPath\nPath to the folder where you want the backup file to be placed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $(Join-Path $Script:DefaultTempPath \"RunbookBackups\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nInstructs the cmdlet to overwrite the destination file if it already exists\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Runbook, Backup, Analysis\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Backup-D365WebConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Backup-D365WebConfig\n\n## SYNOPSIS\nBackup the web.config file\n\n## SYNTAX\n\n```\nBackup-D365WebConfig [[-OutputPath] <String>] [-Force] [<CommonParameters>]\n```\n\n## DESCRIPTION\nWill backup the web.config file located in the AOS / IIS folder\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nBackup-D365WebConfig\n```\n\nWill locate the web.config file, and back it up.\nIt will look for the file in the AOS / IIS folder.\nE.g.\nK:\\AosService\\WebRoot\\web.config.\nIt will save the file to the default location: \"C:\\Temp\\d365fo.tools\\WebConfigBackup\".\n\nA result set example:\n\nFilename   LastModified         File\n--------   ------------         ----\nweb.config 6/29/2021 7:31:04 PM C:\\temp\\d365fo.tools\\WebConfigBackup\\web.config\n\n### EXAMPLE 2\n```\nBackup-D365WebConfig -Force\n```\n\nWill locate the web.config file, back it up, and overwrite if a previous backup file exists.\nIt will look for the file in the AOS / IIS folder.\nE.g.\nK:\\AosService\\WebRoot\\web.config.\nIt will save the file to the default location: \"C:\\Temp\\d365fo.tools\\WebConfigBackup\".\nIt will overwrite any file named web.config in the destination folder.\n\nA result set example:\n\nFilename   LastModified         File\n--------   ------------         ----\nweb.config 6/29/2021 7:31:04 PM C:\\temp\\d365fo.tools\\WebConfigBackup\\web.config\n\n## PARAMETERS\n\n### -OutputPath\nPath to the folder where you want the web.config file to be persisted\n\nDefault is: \"C:\\Temp\\d365fo.tools\\WebConfigBackup\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $(Join-Path $Script:DefaultTempPath \"WebConfigBackup\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nInstructs the cmdlet to overwrite the destination file if it already exists\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: DEV, Tier2, DB, Database, Debug, JIT, LCS, Azure DB\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Backup-D365WifConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Backup-D365WifConfig\n\n## SYNOPSIS\nBackup the wif.config file\n\n## SYNTAX\n\n```\nBackup-D365WifConfig [[-OutputPath] <String>] [-Force] [<CommonParameters>]\n```\n\n## DESCRIPTION\nWill backup the wif.config file located in the AOS / IIS folder\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nBackup-D365WifConfig\n```\n\nWill locate the wif.config file, and back it up.\nIt will look for the file in the AOS / IIS folder.\nE.g.\nK:\\AosService\\WebRoot\\wif.config.\nIt will save the file to the default location: \"C:\\Temp\\d365fo.tools\\WifConfigBackup\".\n\nA result set example:\n\nFilename   LastModified         File\n--------   ------------         ----\nwif.config 6/29/2021 7:31:04 PM C:\\temp\\d365fo.tools\\WifConfigBackup\\wif.config\n\n### EXAMPLE 2\n```\nBackup-D365WifConfig -Force\n```\n\nWill locate the wif.config file, back it up, and overwrite if a previous backup file exists.\nIt will look for the file in the AOS / IIS folder.\nE.g.\nK:\\AosService\\WebRoot\\wif.config.\nIt will save the file to the default location: \"C:\\Temp\\d365fo.tools\\WifConfigBackup\".\nIt will overwrite any file named wif.config in the destination folder.\n\nA result set example:\n\nFilename   LastModified         File\n--------   ------------         ----\nwif.config 6/29/2021 7:31:04 PM C:\\temp\\d365fo.tools\\WifConfigBackup\\wif.config\n\n## PARAMETERS\n\n### -OutputPath\nPath to the folder where you want the web.config file to be persisted\n\nDefault is: \"C:\\Temp\\d365fo.tools\\WifConfigBackup\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $(Join-Path $Script:DefaultTempPath \"WifConfigBackup\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nInstructs the cmdlet to overwrite the destination file if it already exists\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Florian Hopfner (@FH-Inway)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Clear-D365ActiveBroadcastMessageConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Clear-D365ActiveBroadcastMessageConfig\n\n## SYNOPSIS\nClear the active broadcast message config\n\n## SYNTAX\n\n```\nClear-D365ActiveBroadcastMessageConfig [-Temporary] [<CommonParameters>]\n```\n\n## DESCRIPTION\nClear the active broadcast message config from the configuration store\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nClear-D365ActiveBroadcastMessageConfig\n```\n\nThis will clear the active broadcast message configuration from the configuration store.\n\n## PARAMETERS\n\n### -Temporary\nInstruct the cmdlet to only temporarily clear the active broadcast message configuration in the configuration store\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Servicing, Broadcast, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Add-D365BroadcastMessageConfig]()\n\n[Get-D365ActiveBroadcastMessageConfig]()\n\n[Get-D365BroadcastMessageConfig]()\n\n[Remove-D365BroadcastMessageConfig]()\n\n[Send-D365BroadcastMessage]()\n\n[Set-D365ActiveBroadcastMessageConfig]()\n\n"
  },
  {
    "path": "docs/Clear-D365BacpacObject.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Clear-D365BacpacObject\n\n## SYNOPSIS\nClear out sql objects from inside the bacpac/dacpac or zip file\n\n## SYNTAX\n\n### Copy (Default)\n```\nClear-D365BacpacObject -Path <String> -Name <String[]> [-ObjectType <String>] -OutputPath <String>\n [<CommonParameters>]\n```\n\n### Keep\n```\nClear-D365BacpacObject -Path <String> -Name <String[]> [-ObjectType <String>] [-ClearFromSource]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nRemove a set of sql objects from inside a bacpac/dacpac or zip file, before restoring it into your SQL Server / Azure SQL DB\n\nIt will open the file as a zip archive, locate the desired sql object and remove it, so when importing the bacpac the object will not be created\n\nThe default behavior is that you get a copy of the file, where the desired sql objects are removed\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nClear-D365BacpacObject -Path \"C:\\Temp\\AxDB.bacpac\" -ObjectType SqlView -Name \"View2\" -OutputPath \"C:\\Temp\\AXBD_Cleaned.bacpac\"\n```\n\nThis will remove the SqlView \"View2\" from inside the bacpac file.\n\nIt uses \"C:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\nIt uses \"View2\" as the name of the object to delete.\nIt uses \"C:\\Temp\\AXBD_Cleaned.bacpac\" as the OutputPath to where it will store the updated bacpac file.\n\n### EXAMPLE 2\n```\nClear-D365BacpacObject -Path \"C:\\Temp\\AxDB.bacpac\" -ObjectType SqlView -Name \"dbo.View1\",\"View2\" -OutputPath \"C:\\Temp\\AXBD_Cleaned.bacpac\"\n```\n\nThis will remove the SqlView(s) \"dbo.View1\" and \"View2\" from inside the bacpac file.\n\nIt uses \"C:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\nIt uses \"dbo.View1\",\"View2\" as the names of objects to delete.\nIt uses \"C:\\Temp\\AXBD_Cleaned.bacpac\" as the OutputPath to where it will store the updated bacpac file.\n\n### EXAMPLE 3\n```\nClear-D365BacpacObject -Path \"C:\\Temp\\AxDB.bacpac\" -ObjectType SqlIndex -Name \"[dbo].[SalesTable].[CustomIndexName1]\" -ClearFromSource\n```\n\nThis will remove the SqlIndex \"CustomIndexName1\" from the dbo.SalesTable table from inside the bacpac file.\n\nIt uses \"C:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\nIt uses \"\\[dbo\\].\\[SalesTable\\].\\[CustomIndexName1\\]\" as the name of the object to delete.\n\nCaution:\nIt will remove from the source \"C:\\Temp\\AxDB.bacpac\" directly.\nSo if the original file is important for further processing, please consider the risks carefully.\n\n## PARAMETERS\n\n### -Path\nPath to the bacpac/dacpac or zip file that you want to work against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: BacpacFile, File\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Name\nName of the sql object that you want to remove\n\nSupports an array of names\n\nIf a schema name isn't supplied as part of the table name, the cmdlet will prefix it with \"dbo.\"\n\nSome sql objects are 3 part named, which will require that you fill them in with brackets E.g.\n\\[dbo\\].\\[SalesTable\\].\\[CustomIndexName1\\]\n- Index\n- Constraints\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases: ObjectName\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ObjectType\nInstruct the cmdlet, the type of object that you want to remove\n\nAs we are manipulating the bacpac file, we can only handle 1 ObjectType per run\n\nIf you want to remove SqlView and SqlIndex, you will have to run the cmdlet 1 time for SqlViews and 1 time for SqlIndex\n\nSupported types are:\n\"SqlView\", \"SqlTable\", \"SqlIndex\", \"SqlCheckConstraint\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputPath\nPath to where you want the updated bacpac/dacpac or zip file to be saved\n\n```yaml\nType: String\nParameter Sets: Copy\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ClearFromSource\nInstruct the cmdlet to delete sql objects directly from the source file\n\nIt will save disk space and time, because it doesn't have to create a copy of the bacpac file, before deleting sql objects from it\n\n```yaml\nType: SwitchParameter\nParameter Sets: Keep\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nIt will NOT fail, if it can't find any object with the specified name\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Clear-D365BacpacTableData.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Clear-D365BacpacTableData\n\n## SYNOPSIS\nClear out data for a table inside the bacpac/dacpac or zip file\n\n## SYNTAX\n\n### Copy (Default)\n```\nClear-D365BacpacTableData -Path <String> -Table <String[]> -OutputPath <String> [<CommonParameters>]\n```\n\n### Keep\n```\nClear-D365BacpacTableData -Path <String> -Table <String[]> [-ClearFromSource] [<CommonParameters>]\n```\n\n## DESCRIPTION\nRemove all data for a table inside a bacpac/dacpac or zip file, before restoring it into your SQL Server / Azure SQL DB\n\nIt will open the file as a zip archive, locate the desired table and remove the data that otherwise would have been loaded\n\nThe default behavior is that you get a copy of the file, where the desired data is removed\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nClear-D365BacpacTableData -Path \"C:\\Temp\\AxDB.bacpac\" -Table \"BATCHJOBHISTORY\" -OutputPath \"C:\\Temp\\AXBD_Cleaned.bacpac\"\n```\n\nThis will remove the data from the BatchJobHistory table from inside the bacpac file.\n\nIt uses \"C:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\nIt uses \"BATCHJOBHISTORY\" as the Table to delete data from.\nIt uses \"C:\\Temp\\AXBD_Cleaned.bacpac\" as the OutputPath to where it will store the updated bacpac file.\n\n### EXAMPLE 2\n```\nClear-D365BacpacTableData -Path \"C:\\Temp\\AxDB.bacpac\" -Table \"dbo.BATCHHISTORY\",\"BATCHJOBHISTORY\" -OutputPath \"C:\\Temp\\AXBD_Cleaned.bacpac\"\n```\n\nThis will remove the data from the dbo.BatchHistory and BatchJobHistory table from inside the bacpac file.\n\nIt uses \"C:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\nIt uses \"dbo.BATCHHISTORY\",\"BATCHJOBHISTORY\" as the Table to delete data from.\nIt uses \"C:\\Temp\\AXBD_Cleaned.bacpac\" as the OutputPath to where it will store the updated bacpac file.\n\n### EXAMPLE 3\n```\nClear-D365BacpacTableData -Path \"C:\\Temp\\AxDB.bacpac\" -Table \"dbo.BATCHHISTORY\",\"BATCHJOBHISTORY\" -ClearFromSource\n```\n\nThis will remove the data from the dbo.BatchHistory and BatchJobHistory table from inside the bacpac file.\n\nIt uses \"C:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\nIt uses \"dbo.BATCHHISTORY\",\"BATCHJOBHISTORY\" as the Table to delete data from.\n\nCaution:\nIt will remove from the source \"C:\\Temp\\AxDB.bacpac\" directly.\nSo if the original file is important for further processing, please consider the risks carefully.\n\n### EXAMPLE 4\n```\nClear-D365BacpacTableData -Path \"C:\\Temp\\AxDB.bacpac\" -Table \"CustomTableNameThatDoesNotExists\",\"BATCHJOBHISTORY\" -OutputPath \"C:\\Temp\\AXBD_Cleaned.bacpac\" -ErrorAction SilentlyContinue\n```\n\nThis will remove the data from the BatchJobHistory table from inside the bacpac file.\n\nIt uses \"C:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\nIt uses \"CustomTableNameThatDoesNotExists\",\"BATCHJOBHISTORY\" as the Table to delete data from.\nIt respects the respects the ErrorAction \"SilentlyContinue\", and will continue removing tables from the bacpac file, even when some tables are missing.\nIt uses \"C:\\Temp\\AXBD_Cleaned.bacpac\" as the OutputPath to where it will store the updated bacpac file.\n\n## PARAMETERS\n\n### -Path\nPath to the bacpac/dacpac or zip file that you want to work against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: BacpacFile, File\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Table\nName of the table that you want to delete the data for\n\nSupports an array of table names\n\nIf a schema name isn't supplied as part of the table name, the cmdlet will prefix it with \"dbo.\"\n\nSupports wildcard searching e.g.\n\"Sales*\" will delete all \"dbo.Sales*\" tables in the bacpac file\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases: TableName\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputPath\nPath to where you want the updated bacpac/dacpac or zip file to be saved\n\n```yaml\nType: String\nParameter Sets: Copy\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ClearFromSource\nInstruct the cmdlet to delete tables directly from the source file\n\nIt will save disk space and time, because it doesn't have to create a copy of the bacpac file, before deleting tables from it\n\n```yaml\nType: SwitchParameter\nParameter Sets: Keep\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Bacpac, Servicing, Data, Deletion, SqlPackage\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Clear-D365MonitorData.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Clear-D365MonitorData\n\n## SYNOPSIS\nClear the monitoring data from a Dynamics 365 for Finance & Operations machine\n\n## SYNTAX\n\n```\nClear-D365MonitorData [[-Path] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nClear the monitoring data that is filling up the service drive on a Dynamics 365 for Finance & Operations\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nClear-D365MonitorData\n```\n\nThis will delete all the files that are located in the default path on the machine.\nSome files might be locked by a process, but the cmdlet will attemp to delete all files.\n\n## PARAMETERS\n\n### -Path\nThe path to where the monitoring data is located\n\nThe default value is the \"ServiceDrive\" (j:\\ | k:\\\\) and the \\MonAgentData\\SingleAgent\\Tables folder structure\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: (Join-Path $script:ServiceDrive \"\\MonAgentData\\SingleAgent\\Tables\")\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Monitor, MonitorData, MonitorAgent, CleanUp, Servicing\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Clear-D365TempDbTables.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version: https://msdyn365fo.wordpress.com/2019/12/18/cleanup-tempdb-tables-in-a-msdyn365fo-sandbox-environment/\nschema: 2.0.0\n---\n\n# Clear-D365TempDbTables\n\n## SYNOPSIS\nCleanup TempDB tables in Microsoft Dynamics 365 for Finance and Operations environment\n\n## SYNTAX\n\n```\nClear-D365TempDbTables [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>]\n [[-SqlPwd] <String>] [[-Days] <Int32>] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nThis will cleanup X days of TempDB tables\n\nThe reason behind this process is that sp_updatestats takes significantly longer depending on the number of TempDB tables in the system\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nClear-D365TempDbTables -Days 7\n```\n\nThis will cleanup old tempdb tables.\nIt will use 7 as the Days parameter.\n\nThe remaining parameters will use their default values, which are provided by the tools.\n\n## PARAMETERS\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Days\nTemp tables older than this Days input will be dropped\n\nThe default value is 7 (days)\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: 7\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Alex Kwitny (@AlexOnDAX)\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThis cmdlet is based on the findings from Paul Heisterkamp (@braul)\n\nSee his blog for more info:\nhttps://msdyn365fo.wordpress.com/2019/12/18/cleanup-tempdb-tables-in-a-msdyn365fo-sandbox-environment/\n\n## RELATED LINKS\n\n[https://msdyn365fo.wordpress.com/2019/12/18/cleanup-tempdb-tables-in-a-msdyn365fo-sandbox-environment/](https://msdyn365fo.wordpress.com/2019/12/18/cleanup-tempdb-tables-in-a-msdyn365fo-sandbox-environment/)\n\n[https://github.com/PaulHeisterkamp/d365fo.blog/blob/master/Tools/SQL/DropTempDBTables.sql](https://github.com/PaulHeisterkamp/d365fo.blog/blob/master/Tools/SQL/DropTempDBTables.sql)\n\n"
  },
  {
    "path": "docs/ConvertTo-D365Dacpac.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version: https://msdyn365fo.wordpress.com/2019/12/18/cleanup-tempdb-tables-in-a-msdyn365fo-sandbox-environment/\nschema: 2.0.0\n---\n\n# ConvertTo-D365Dacpac\n\n## SYNOPSIS\nConvert bacpac file to dacpac\n\n## SYNTAX\n\n```\nConvertTo-D365Dacpac [-Path] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\nConvert bacpac file to dacpac\n\nIt will extract the origin.xml file from the file, and set the \\<ContainsExportedData\\>false\\</ContainsExportedData\\> for the file to be valid to be used as a dacpac file\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nConvertTo-D365Dacpac -Path \"C:\\Temp\\AxDB.bacpac\"\n```\n\nThis will convert the bacpac file into a dacpac file.\nIt will extract the origin.xml file, update it and apply it to the file.\nIt will rename the file into a dacpac.\n\nThe source file will be manipulated, so be careful to have an extra copy of the file.\n\n## PARAMETERS\n\n### -Path\nPath to the bacpac file that you want to work against\n\nIt can also be a zip file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: BacpacFile, File\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Bacpac, Servicing, Data, SqlPackage, Dacpac, Table\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Disable-D365Exception.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Disable-D365Exception\n\n## SYNOPSIS\nDisables throwing of exceptions\n\n## SYNTAX\n\n```\nDisable-D365Exception [<CommonParameters>]\n```\n\n## DESCRIPTION\nRestore the default exception behavior of the module to not support throwing exceptions\n\nUseful when the default behavior was changed with Enable-D365Exception and the default behavior should be restored\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nDisable-D365Exception\n```\n\nThis will restore the default behavior of the module to not support throwing exceptions.\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Exception, Exceptions, Warning, Warnings\n\nAuthor: Florian Hopfner (@FH-Inway)\n\n## RELATED LINKS\n\n[Enable-D365Exception]()\n\n"
  },
  {
    "path": "docs/Disable-D365Flight.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version: https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages#features-flighted-in-data-management-and-enabling-flighted-features\nschema: 2.0.0\n---\n\n# Disable-D365Flight\n\n## SYNOPSIS\nUsed to disable a flight\n\n## SYNTAX\n\n```\nDisable-D365Flight [-FlightName] <String> [[-DatabaseServer] <String>] [[-DatabaseName] <String>]\n [[-SqlUser] <String>] [[-SqlPwd] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nProvides a method for disabling a flight in D365FO.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nDisable-D365Flight -FlightName DMFEnableAllCompanyExport\n```\n\nDisables the flight DMFEnableAllCompanyExport\n\n## PARAMETERS\n\n### -FlightName\nName of the flight to disable\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Flight, Flighting\n\nAuthor: Frank Hüther (@FrankHuether)\n\nThe DataAccess.FlightingServiceCatalogID must already be set in the web.config file.\n\nAt no circumstances can this cmdlet be used to enable a flight in a PROD environment.\n\n## RELATED LINKS\n\n[https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages#features-flighted-in-data-management-and-enabling-flighted-features](https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages#features-flighted-in-data-management-and-enabling-flighted-features)\n\n"
  },
  {
    "path": "docs/Disable-D365IISPreload.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Disable-D365IISPreload\n\n## SYNOPSIS\nDisables IIS Preload for the AOSService application pool and website.\n\n## SYNTAX\n\n```\nDisable-D365IISPreload [<CommonParameters>]\n```\n\n## DESCRIPTION\nReverts IIS Preload settings for the AOSService application:\n- Sets Application Pool Start Mode to OnDemand\n- Sets Idle Time-out to 0 (default)\n- Disables Preload on the AOSService website\n- Sets doAppInitAfterRestart to false (if Application Initialization is installed)\n- Restores previous IIS Preload configuration from backup if available\n- Restores or removes the initializationPage property as appropriate\n- Uninstalls IIS Application Initialization feature if it was not installed in the backup\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nDisable-D365IISPreload\n```\n\nDisables IIS Preload for the AOSService application pool and website, restoring previous settings from backup if available.\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Florian Hopfner (FH-Inway)\nBased on Denis Trunin's article \"Enable IIS Preload to Speed Up Restart After X++ Compile\" (https://www.linkedin.com/pulse/enable-iis-preload-speed-up-restart-after-x-compile-denis-trunin-86j5c)\nWritten with GitHub Copilot GPT-4.1, mostly in agent mode.\nSee commits for prompts.\n\n## RELATED LINKS\n\n[Get-D365IISPreload]()\n\n[Enable-D365IISPreload]()\n\n"
  },
  {
    "path": "docs/Disable-D365MaintenanceMode.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Disable-D365MaintenanceMode\n\n## SYNOPSIS\nSets the environment back into operating state\n\n## SYNTAX\n\n```\nDisable-D365MaintenanceMode [[-MetaDataDir] <String>] [[-BinDir] <String>] [[-DatabaseServer] <String>]\n [[-DatabaseName] <String>] [[-SqlUser] <String>] [[-SqlPwd] <String>] [[-LogPath] <String>]\n [-ShowOriginalProgress] [-OutputCommandOnly] [<CommonParameters>]\n```\n\n## DESCRIPTION\nSets the Dynamics 365 environment back into operating / running state after it has been in maintenance mode.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nDisable-D365MaintenanceMode\n```\n\nOn VHD based environments, this will execute the Microsoft.Dynamics.AX.Deployment.Setup.exe with the default values that was pulled from the environment and put the environment into the operate / running state.\nOn cloud hosted environments, a SQL script is used instead.\n\n### EXAMPLE 2\n```\nDisable-D365MaintenanceMode -ShowOriginalProgress\n```\n\nOn VHD based environments, this will execute the Microsoft.Dynamics.AX.Deployment.Setup.exe with the default values that was pulled from the environment and put the environment into the operate / running state.\nOn cloud hosted environments, a SQL script is used instead.\nThe output from stopping the services will be written to the console / host.\nThe output from the \"deployment\" process will be written to the console / host.\nThe output from starting the services will be written to the console / host.\n\n## PARAMETERS\n\n### -MetaDataDir\nThe path to the meta data directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: \"$Script:MetaDataDir\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nThe path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 7\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\MaintenanceMode\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable or SQL script and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: MaintenanceMode, Maintenance, License, Configuration, Servicing\n\nAuthor: Mötz Jensen (@splaxi)\nAuthor: Tommy Skaue (@skaue)\n\nOn VHD based environments with administrator privileges:\nThe cmdlet wraps the execution of Microsoft.Dynamics.AX.Deployment.Setup.exe and parses the parameters needed.\n\nWithout administrator privileges or on cloud hosted environments:\nWill stop all services, execute a SQL script and start all services.\n\n## RELATED LINKS\n\n[Enable-D365MaintenanceMode]()\n\n[Get-D365MaintenanceMode]()\n\n"
  },
  {
    "path": "docs/Disable-D365SqlChangeTracking.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Disable-D365SqlChangeTracking\n\n## SYNOPSIS\nDisable Change Tracking for the environment\n\n## SYNTAX\n\n```\nDisable-D365SqlChangeTracking [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>]\n [[-SqlPwd] <String>] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nDisables the SQL Server Change Tracking for the environments database and all tables inside the database\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nDisable-D365SqlChangeTracking\n```\n\nThis will disable the Change Tracking on the Sql Server.\n\n## PARAMETERS\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: MaintenanceMode, Maintenance, License, Configuration, Servicing\n\nAuthor: Mötz Jensen (@splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Disable-D365User.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Disable-D365User\n\n## SYNOPSIS\nDisables the user in D365FO\n\n## SYNTAX\n\n```\nDisable-D365User [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>]\n [[-SqlPwd] <String>] [[-Email] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nSets the enabled to 0 in the userinfo table.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nDisable-D365User\n```\n\nThis will Disable all users for the environment\n\n### EXAMPLE 2\n```\nDisable-D365User -Email \"claire@contoso.com\"\n```\n\nThis will Disable the user with the email address \"claire@contoso.com\"\n\n### EXAMPLE 3\n```\nDisable-D365User -Email \"*contoso.com\"\n```\n\nThis will Disable all users that matches the search \"*contoso.com\" in their email address\n\n## PARAMETERS\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Email\nThe search string to select which user(s) should be disabled.\n\nThe parameter supports wildcards.\nE.g.\n-Email \"*@contoso.com*\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: *\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: User, Users, Security, Configuration, Permission\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Enable-D365Exception.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Enable-D365Exception\n\n## SYNOPSIS\nEnable exceptions to be thrown\n\n## SYNTAX\n\n```\nEnable-D365Exception [<CommonParameters>]\n```\n\n## DESCRIPTION\nChange the default exception behavior of the module to support throwing exceptions\n\nUseful when the module is used in an automated fashion, like inside Azure DevOps pipelines and large PowerShell scripts\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nEnable-D365Exception\n```\n\nThis will for the rest of the current PowerShell session make sure that exceptions will be thrown.\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Exception, Exceptions, Warning, Warnings\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Disable-D365Exception]()\n\n"
  },
  {
    "path": "docs/Enable-D365Flight.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Enable-D365Flight\n\n## SYNOPSIS\nUsed to enable a flight\n\n## SYNTAX\n\n```\nEnable-D365Flight [-FlightName] <String> [[-DatabaseServer] <String>] [[-DatabaseName] <String>]\n [[-SqlUser] <String>] [[-SqlPwd] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nProvides a method for enabling a flight in D365FO.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nEnable-D365Flight -FlightName DMFEnableAllCompanyExport\n```\n\nEnables the flight DMFEnableAllCompanyExport\n\n## PARAMETERS\n\n### -FlightName\nName of the flight to enable\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Flight, Flighting\n\nAuthor: Frank Hüther (@FrankHuether)\n\nThe DataAccess.FlightingServiceCatalogID must already be set in the web.config file.\nhttps://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages#features-flighted-in-data-management-and-enabling-flighted-features\n\nAt no circumstances can this cmdlet be used to enable a flight in a PROD environment.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Enable-D365IISPreload.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Enable-D365IISPreload\n\n## SYNOPSIS\nEnables IIS Preload for the AOSService application pool and website.\n\n## SYNTAX\n\n```\nEnable-D365IISPreload [[-BaseUrl] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nConfigures IIS to preload the AOSService application, improving startup time after X++ compile.\n- Sets Application Pool Start Mode to AlwaysRunning\n- Sets Idle Time-out to 0\n- Enables Preload on the AOSService website\n- Sets doAppInitAfterRestart to true (if Application Initialization is installed)\n- Optionally sets the initializationPage to a custom base URL\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nEnable-D365IISPreload\n```\n\nThis will enable IIS Preload and set the initializationPage using the automatically detected base URL.\n\n### EXAMPLE 2\n```\nEnable-D365IISPreload -BaseUrl \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\"\n```\n\nThis will enable IIS Preload and set the initializationPage to https://usnconeboxax1aos.cloud.onebox.dynamics.com/?mi=DefaultDashboard\n\n## PARAMETERS\n\n### -BaseUrl\nThe base URL to use for the initializationPage setting in IIS Application Initialization.\nIf not provided, the function will attempt to determine the base URL automatically using Get-D365Url.\nExample: https://usnconeboxax1aos.cloud.onebox.dynamics.com\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Florian Hopfner (FH-Inway)\nBased on Denis Trunin's article \"Enable IIS Preload to Speed Up Restart After X++ Compile\" (https://www.linkedin.com/pulse/enable-iis-preload-speed-up-restart-after-x-compile-denis-trunin-86j5c)\nWritten with GitHub Copilot GPT-4.1, mostly in agent mode.\nSee commits for prompts.\n\n## RELATED LINKS\n\n[Get-D365IISPreload]()\n\n[Disable-D365IISPreload]()\n\n"
  },
  {
    "path": "docs/Enable-D365MaintenanceMode.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Enable-D365MaintenanceMode\n\n## SYNOPSIS\nSets the environment into maintenance mode\n\n## SYNTAX\n\n```\nEnable-D365MaintenanceMode [[-MetaDataDir] <String>] [[-BinDir] <String>] [[-DatabaseServer] <String>]\n [[-DatabaseName] <String>] [[-SqlUser] <String>] [[-SqlPwd] <String>] [[-LogPath] <String>]\n [-ShowOriginalProgress] [-OutputCommandOnly] [<CommonParameters>]\n```\n\n## DESCRIPTION\nSets the Dynamics 365 environment into maintenance mode to enable the user to update the license configuration\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nEnable-D365MaintenanceMode\n```\n\nOn VHD based environments, this will execute the Microsoft.Dynamics.AX.Deployment.Setup.exe with the default values that was pulled from the environment and put the environment into the maintenance mode.\nOn cloud hosted environments, a SQL script is used instead.\n\n### EXAMPLE 2\n```\nEnable-D365MaintenanceMode -ShowOriginalProgress\n```\n\nOn VHD based environments, this will execute the Microsoft.Dynamics.AX.Deployment.Setup.exe with the default values that was pulled from the environment and put the environment into the maintenance mode.\nOn cloud hosted environments, a SQL script is used instead.\nThe output from stopping the services will be written to the console / host.\nThe output from the \"deployment\" process will be written to the console / host.\nThe output from starting the services will be written to the console / host.\n\n## PARAMETERS\n\n### -MetaDataDir\nThe path to the meta data directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: \"$Script:MetaDataDir\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nThe path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 7\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\MaintenanceMode\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable or SQL script and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: MaintenanceMode, Maintenance, License, Configuration, Servicing\n\nAuthor: Mötz Jensen (@splaxi)\nAuthor: Tommy Skaue (@skaue)\n\nOn VHD based environments with administrator privileges:\nThe cmdlet wraps the execution of Microsoft.Dynamics.AX.Deployment.Setup.exe and parses the parameters needed.\n\nWithout administrator privileges or on cloud hosted environments:\nWill stop all services, execute a SQL script and starts the AOS service (other services are not needed during maintenance mode).\n\n## RELATED LINKS\n\n[Get-D365MaintenanceMode]()\n\n[Disable-D365MaintenanceMode]()\n\n"
  },
  {
    "path": "docs/Enable-D365SqlChangeTracking.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Enable-D365SqlChangeTracking\n\n## SYNOPSIS\nEnable Change Tracking for the environment\n\n## SYNTAX\n\n```\nEnable-D365SqlChangeTracking [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>]\n [[-SqlPwd] <String>] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nEnable the SQL Server Change Tracking for the environments database\n\nIt is a requirement for the Data Entities refresh to be able to complete correctly\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nEnable-D365SqlChangeTracking\n```\n\nThis will enable the Change Tracking on the Sql Server.\n\n## PARAMETERS\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: MaintenanceMode, Maintenance, License, Configuration, Servicing\n\nAuthor: Mötz Jensen (@splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Enable-D365User.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Enable-D365User\n\n## SYNOPSIS\nEnables the user in D365FO\n\n## SYNTAX\n\n```\nEnable-D365User [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>]\n [[-SqlPwd] <String>] [[-Email] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nSets the enabled to 1 in the userinfo table\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nEnable-D365User\n```\n\nThis will enable all users for the environment\n\n### EXAMPLE 2\n```\nEnable-D365User -Email \"claire@contoso.com\"\n```\n\nThis will enable the user with the email address \"claire@contoso.com\"\n\n### EXAMPLE 3\n```\nEnable-D365User -Email \"*contoso.com\"\n```\n\nThis will enable all users that matches the search \"*contoso.com\" in their email address\n\n## PARAMETERS\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Email\nThe search string to select which user(s) should be enabled\n\nThe parameter supports wildcards.\nE.g.\n-Email \"*@contoso.com*\"\n\nDefault value is \"*\" to update all users\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: *\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: User, Users, Security, Configuration, Permission\n\nAuthor: Mötz Jensen\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Export-D365BacpacModelFile.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Export-D365BacpacModelFile\n\n## SYNOPSIS\nExtract the \"model.xml\" from the bacpac file\n\n## SYNTAX\n\n```\nExport-D365BacpacModelFile [-Path] <String> [[-OutputPath] <String>] [-Force] [<CommonParameters>]\n```\n\n## DESCRIPTION\nExtract the \"model.xml\" file from inside the bacpac file\n\nThis can be used to update SQL Server options for how the SqlPackage.exe should import the bacpac file into your SQL Server / Azure SQL DB\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nExport-D365BacpacModelFile -Path \"c:\\Temp\\AxDB.bacpac\"\n```\n\nThis will extract the \"model.xml\" file from inside the bacpac file.\n\nIt uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\nIt uses the default value \"c:\\temp\\d365fo.tools\" as the OutputPath to where it will store the extracted \"bacpac.model.xml\" file.\n\n### EXAMPLE 2\n```\nExport-D365BacpacModelFile -Path \"c:\\Temp\\AxDB.bacpac\" -OutputPath \"c:\\Temp\\model.xml\" -Force\n```\n\nThis will extract the \"model.xml\" file from inside the bacpac file.\n\nIt uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\nIt uses \"c:\\Temp\\model.xml\" as the OutputPath to where it will store the extracted \"model.xml\" file.\n\nIt will override the \"c:\\Temp\\model.xml\" if already present.\n\n### EXAMPLE 3\n```\nExport-D365BacpacModelFile -Path \"c:\\Temp\\AxDB.bacpac\" | Get-D365BacpacSqlOptions\n```\n\nThis will display all the SQL Server options configured in the bacpac file.\nFirst it will export the bacpac.model.xml from the \"c:\\Temp\\AxDB.bacpac\" file, using the Export-D365BacpacModelFile function.\nThe output from Export-D365BacpacModelFile will be piped into the Get-D365BacpacSqlOptions function.\n\n## PARAMETERS\n\n### -Path\nPath to the bacpac file that you want to work against\n\nIt can also be a zip file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: BacpacFile, File\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputPath\nPath to where you want the updated bacpac file to be saved\n\nDefault value is: \"c:\\temp\\d365fo.tools\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nSwitch to instruct the cmdlet to overwrite the \"model.xml\" specified in the OutputPath\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Bacpac, Servicing, Data, SqlPackage, Sql Server Options, Collation\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Export-D365Model.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Export-D365Model\n\n## SYNOPSIS\nExport a model from Dynamics 365 for Finance & Operations\n\n## SYNTAX\n\n```\nExport-D365Model [-Path] <String> [-Model] <String> [-Force] [[-BinDir] <String>] [[-MetaDataDir] <String>]\n [[-LogPath] <String>] [-ShowOriginalProgress] [-OutputCommandOnly] [<CommonParameters>]\n```\n\n## DESCRIPTION\nExport a model from a Dynamics 365 for Finance & Operations environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nExport-D365Model -Path c:\\temp\\d365fo.tools -Model CustomModelName\n```\n\nThis will export the \"CustomModelName\" model from the default PackagesLocalDirectory path.\nIt export the model to the \"c:\\temp\\d365fo.tools\" location.\n\n## PARAMETERS\n\n### -Path\nPath to the folder where you want to save the model file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Model\nName of the model that you want to work against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Modelname\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Force\nInstruct the cmdlet to overwrite already existing file\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the AOS service PackagesLocalDirectory\\bin\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: \"$Script:PackageDirectory\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetaDataDir\nThe path to the meta data directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: \"$Script:MetaDataDir\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nThe path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 5\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModelUtilExport\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: ModelUtil, Axmodel, Model, Export\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Export-D365SecurityDetails.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Export-D365SecurityDetails\n\n## SYNOPSIS\nExtract details from a User Interface Security file\n\n## SYNTAX\n\n```\nExport-D365SecurityDetails [-FilePath] <String> [[-OutputDirectory] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nExtracts and partitions the security details from an User Interface Security file into the same structure as AOT security files\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nExport-D365SecurityDetails -FilePath C:\\temp\\d365fo.tools\\SecurityDatabaseCustomizations.xml\n```\n\nThis will grab all the details inside the \"C:\\temp\\d365fo.tools\\SecurityDatabaseCustomizations.xml\" file and extract that into the default path \"C:\\temp\\d365fo.tools\\security-extraction\"\n\n## PARAMETERS\n\n### -FilePath\nPath to the User Interface Security XML file you want to work against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Path\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputDirectory\nPath to the folder where the cmdlet will output and structure the details from the file.\nThe cmdlet will create a sub folder named like the input file.\n\nDefault value is: \"C:\\temp\\d365fo.tools\\security-extraction\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Output\n\nRequired: False\nPosition: 2\nDefault value: C:\\temp\\d365fo.tools\\security-extraction\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Security, Configuration, Permission, Development\n\nAuthor: Mötz Jensen (@splaxi)\n\nThe work and design of this cmdlet is based on the findings by Alex Meyer (@alexmeyer_ITGuy).\n\nHe wrote about his findings on his blog:\nhttps://alexdmeyer.com/2018/09/26/converting-d365fo-user-interface-security-customizations-export-to-aot-security-xml-files/\n\nHe published a github repository:\n\nhttps://github.com/ameyer505/D365FOSecurityConverter\n\nAll credits goes to Alex Meyer\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Find-D365Command.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Find-D365Command\n\n## SYNOPSIS\nFinds d365fo.tools commands searching through the inline help text\n\n## SYNTAX\n\n```\nFind-D365Command [[-Pattern] <String>] [[-Tag] <String[]>] [[-Author] <String>] [[-MinimumVersion] <String>]\n [[-MaximumVersion] <String>] [-Rebuild] [-EnableException] [-WhatIf] [-Confirm] [<CommonParameters>]\n```\n\n## DESCRIPTION\nFinds d365fo.tools commands searching through the inline help text, building a consolidated json index and querying it because Get-Help is too slow\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nFind-D365Command \"snapshot\"\n```\n\nFor lazy typers: finds all commands searching the entire help for \"snapshot\"\n\n### EXAMPLE 2\n```\nFind-D365Command -Pattern \"snapshot\"\n```\n\nFor rigorous typers: finds all commands searching the entire help for \"snapshot\"\n\n### EXAMPLE 3\n```\nFind-D365Command -Tag copy\n```\n\nFinds all commands tagged with \"copy\"\n\n### EXAMPLE 4\n```\nFind-D365Command -Tag copy,user\n```\n\nFinds all commands tagged with BOTH \"copy\" and \"user\"\n\n### EXAMPLE 5\n```\nFind-D365Command -Author Mötz\n```\n\nFinds every command whose author contains \"Mötz\"\n\n### EXAMPLE 6\n```\nFind-D365Command -Author Mötz -Tag copy\n```\n\nFinds every command whose author contains \"Mötz\" and it tagged as \"copy\"\n\n### EXAMPLE 7\n```\nFind-D365Command -Pattern snapshot -Rebuild\n```\n\nFinds all commands searching the entire help for \"snapshot\", rebuilding the index (good for developers)\n\n## PARAMETERS\n\n### -Pattern\nSearches help for all commands in d365fo.tools for the specified pattern and displays all results\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Tag\nFinds all commands tagged with this auto-populated tag\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Author\nFinds all commands tagged with this author\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MinimumVersion\nFinds all commands tagged with this auto-populated minimum version\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MaximumVersion\nFinds all commands tagged with this auto-populated maximum version\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Rebuild\nRebuilds the index\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nBy default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message.\nThis avoids overwhelming you with \"sea of red\" exceptions, but is inconvenient because it basically disables advanced scripting.\nUsing this switch turns this \"nice by default\" feature off and enables you to catch exceptions with your own try/catch.\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases: Silent\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -WhatIf\nDisplays what would happen if the command is run\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases: wi\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Confirm\nConfirms overwrite of index\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases: cf\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Find, Help, Command\nAuthor: Mötz Jensen (@Splaxi)\n\nLicense: MIT https://opensource.org/licenses/MIT\n\nThis cmdlet / function is copy & paste implementation based on the Find-DbaCommand from the dbatools.io project\n\nOriginal author: Simone Bizzotto (@niphold)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365AOTObject.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365AOTObject\n\n## SYNOPSIS\nSearch for AOT object\n\n## SYNTAX\n\n```\nGet-D365AOTObject [-Path] <String> [[-ObjectType] <String[]>] [[-Name] <String>] [-SearchInPackages]\n [-IncludePath] [<CommonParameters>]\n```\n\n## DESCRIPTION\nEnables you to search for different AOT objects\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365AOTObject -Name *flush* -ObjectType AxClass -Path \"C:\\AOSService\\PackagesLocalDirectory\\ApplicationFoundation\"\n```\n\nThis will search inside the ApplicationFoundation package for all AxClasses that matches the search *flush*.\n\n### EXAMPLE 2\n```\nGet-D365AOTObject -Name *flush* -ObjectType AxClass -IncludePath -Path \"C:\\AOSService\\PackagesLocalDirectory\\ApplicationFoundation\"\n```\n\nThis will search inside the ApplicationFoundation package for all AxClasses that matches the search *flush* and include the full path to the files.\n\n### EXAMPLE 3\n```\nGet-D365InstalledPackage -Name Application* | Get-D365AOTObject -Name *flush* -ObjectType AxClass\n```\n\nThis searches for all packages that matches Application* and pipes them into Get-D365AOTObject which will search for all AxClasses that matches the search *flush*.\n\n### EXAMPLE 4\n```\nGet-D365AOTObject -Path \"C:\\AOSService\\PackagesLocalDirectory\\*\" -Name *flush* -ObjectType AxClass -SearchInPackages\n```\n\nThis is an advanced example and shouldn't be something you resolve to every time.\n\nThis will search across all packages and will look for the all AxClasses that matches the search *flush*.\nIt will NOT search in the XppMetaData directory for each package.\n\nThis can stress your system.\n\n## PARAMETERS\n\n### -Path\nPath to the package that you want to work against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: PackageDirectory\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -ObjectType\nThe type of AOT object you're searching for\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases: Type\n\nRequired: False\nPosition: 2\nDefault value: @(\"AxClass\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Name\nName of the object that you're looking for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"Work*status\"\n\nDefault value is \"*\" which will search for all objects\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SearchInPackages\nSwitch to instruct the cmdlet to search in packages directly instead\nof searching in the XppMetaData directory under a given package\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -IncludePath\nSwitch to instruct the cmdlet to include the path for the object found\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365ActiveAzureStorageConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365ActiveAzureStorageConfig\n\n## SYNOPSIS\nGet active Azure Storage Account configuration\n\n## SYNTAX\n\n```\nGet-D365ActiveAzureStorageConfig [-OutputAsPsCustomObject] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet active Azure Storage Account configuration object from the configuration store\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365ActiveAzureStorageConfig\n```\n\nThis will get the active Azure Storage configuration.\n\n### EXAMPLE 2\n```\nGet-D365ActiveAzureStorageConfig -OutputAsPsCustomObject\n```\n\nThis will get the active Azure Storage configuration.\nThe object will be output as a PsCustomObject, for you to utilize across your scripts.\n\n## PARAMETERS\n\n### -OutputAsPsCustomObject\nInstruct the cmdlet to return a PsCustomObject object\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Azure, Azure Storage, Config, Configuration, Token, Blob, Container\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365ActiveBroadcastMessageConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365ActiveBroadcastMessageConfig\n\n## SYNOPSIS\nGet active broadcast message configuration\n\n## SYNTAX\n\n```\nGet-D365ActiveBroadcastMessageConfig [-OutputAsHashtable] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet active broadcast message configuration from the configuration store\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365ActiveBroadcastMessageConfig\n```\n\nThis will get the active broadcast message configuration.\n\n## PARAMETERS\n\n### -OutputAsHashtable\nInstruct the cmdlet to return a hastable object\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Servicing, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Add-D365BroadcastMessageConfig]()\n\n[Clear-D365ActiveBroadcastMessageConfig]()\n\n[Get-D365BroadcastMessageConfig]()\n\n[Remove-D365BroadcastMessageConfig]()\n\n[Send-D365BroadcastMessage]()\n\n[Set-D365ActiveBroadcastMessageConfig]()\n\n"
  },
  {
    "path": "docs/Get-D365AzureDevOpsNuget.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365AzureDevOpsNuget\n\n## SYNOPSIS\nGet Azure DevOps nugets\n\n## SYNTAX\n\n```\nGet-D365AzureDevOpsNuget [-Url] <String> [-FeedName] <String> [-PeronalAccessToken] <String> [[-Name] <String>]\n [-Latest] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet Azure DevOps nugets from a feed, to list all available details\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365AzureDevOpsNuget -Uri \"https://dev.azure.com/Contoso/Financials\" -FeedName \"AASBuild365\" -PeronalAccessToken \"m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny\"\n```\n\nThis will list all packages / nugets from the Azure DevOps feed.\nForeach packacge, it will list all available versions.\nThe http request will be going to the Uri \"https://dev.azure.com/Contoso/Financials\".\nThe feed is identified by the FeedName \"AASBuild365\".\nThe request will authenticate with the PeronalAccessToken \"m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny\"\n\n### EXAMPLE 2\n```\nGet-D365AzureDevOpsNuget -Uri \"https://dev.azure.com/Contoso/Financials\" -FeedName \"AASBuild365\" -PeronalAccessToken \"m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny\" -Latest\n```\n\nThis will list all packages / nugets from the Azure DevOps feed.\nForeach packacge, it will only list the latest version (highest).\nThe http request will be going to the Uri \"https://dev.azure.com/Contoso/Financials\".\nThe feed is identified by the FeedName \"AASBuild365\".\nThe request will authenticate with the PeronalAccessToken \"m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny\"\nThe cmdlet will only output the latest version by the Latest switch.\n\n### EXAMPLE 3\n```\n$currentNugets = Get-D365AzureDevOpsNuget -Uri \"https://dev.azure.com/Contoso/Financials\" -FeedName \"AASBuild365\" -PeronalAccessToken \"m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny\" -Latest\n```\n\nPS C:\\\\\\> foreach ($item in $currentNugets) {\nPS C:\\\\\\>     $lcsNugets = Get-D365LcsAssetFile -FileType NuGetPackage -AssetFilename \"$($item.Name)*\"\nPS C:\\\\\\>     foreach ($itemInner in $lcsNugets) {\nPS C:\\\\\\>         if ($itemInner.FileName -Match \"\\d+\\.\\d+\\.\\d+\\.\\d+\") {\nPS C:\\\\\\>             if ($(\\[Version\\]$Matches\\[0\\]) -gt \\[Version\\]$item.Version) {\nPS C:\\\\\\>                 $itemInner\nPS C:\\\\\\>             }\nPS C:\\\\\\>         }\nPS C:\\\\\\>     }\nPS C:\\\\\\> }\n\nThis will fetch all latest nugets from the Azure DevOps artifacts feed (nuget).\nFor each nuget found, it will fetch matching nugets from the LCS Asset Library and return those that have a higher version.\n\nThis can be used to automatically download and push the latest nuget from LCS to Azure DevOps.\nNeeds to be put into work with Invoke-D365AzureDevOpsNugetPush\n\n## PARAMETERS\n\n### -Url\nThe Azure DevOps url that you want to work against\n\nIt needs to be the full url for the organization and project, e.g.\n\"https://dev.azure.com/Contoso/Financials\" - where Contoso is the organization and the Financials is the project.\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Uri\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FeedName\nName of the feed that you want to work against\n\nThe feed name is found under the Artifacts area in Azure DevOps\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PeronalAccessToken\nThe Personal Access Token that you need to provide for the cmdlet to be able to communicate with the Azure DevOps REST services\n\nThe Personal Access Token is configured via the Azure DevOps portal, on your own account\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Name\nName of the package / nuget that you are searching for\n\nSupports wildcard searching e.g.\n\"*platform*\" will output all packages / nugets that matches the search pattern\n\nDefault value is \"*\" which will search for all packages / nugets\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: PackageName\n\nRequired: False\nPosition: 4\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Latest\nInstruct the cmdlet to only fetch the latest package / nuget based on the version (highest)\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365AzureStorageConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365AzureStorageConfig\n\n## SYNOPSIS\nGet Azure Storage Account configs\n\n## SYNTAX\n\n```\nGet-D365AzureStorageConfig [[-Name] <String>] [-OutputAsHashtable] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet all Azure Storage Account configuration objects from the configuration store\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365AzureStorageConfig\n```\n\nThis will show all Azure Storage Account configs\n\n### EXAMPLE 2\n```\nGet-D365AzureStorageConfig -OutputAsHashtable\n```\n\nThis will show all Azure Storage Account configs.\nEvery object will be output as a hashtable, for you to utilize as parameters for other cmdlets.\n\n## PARAMETERS\n\n### -Name\nThe name of the Azure Storage Account you are looking for\n\nDefault value is \"*\" to display all Azure Storage Account configs\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputAsHashtable\nInstruct the cmdlet to return a hastable object\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Azure, Azure Storage, Config, Configuration, Token, Blob, Container\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365AzureStorageFile.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365AzureStorageFile\n\n## SYNOPSIS\nGet file information from Azure Storage\n\n## SYNTAX\n\n### Default (Default)\n```\nGet-D365AzureStorageFile [-AccountId <String>] [-AccessToken <String>] [-SAS <String>] [-Container <String>]\n [-Name <String>] [<CommonParameters>]\n```\n\n### Latest\n```\nGet-D365AzureStorageFile [-AccountId <String>] [-AccessToken <String>] [-SAS <String>] [-Container <String>]\n [-Latest] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet information for files from an Azure Storage Account\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365AzureStorageFile -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Container \"backupfiles\"\n```\n\nThis will get information for all files in the blob container \"backupfiles\".\nIt will use the AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" to gain access.\n\n### EXAMPLE 2\n```\nGet-D365AzureStorageFile -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Container \"backupfiles\" -Latest\n```\n\nThis will get information for the latest (newest) file from the blob container \"backupfiles\".\nIt will use the AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" to gain access to the container.\n\n### EXAMPLE 3\n```\nGet-D365AzureStorageFile -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Container \"backupfiles\" -Name \"*UAT*\"\n```\n\nThis will get information for all files in the blob container \"backupfiles\" that fits the \"*UAT*\" search value.\nIt will use the AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" to gain access to the container.\n\n### EXAMPLE 4\n```\nGet-D365AzureStorageFile -AccountId \"miscfiles\" -SAS \"sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" -Container \"backupfiles\" -Latest\n```\n\nThis will get information for the latest (newest) file from the blob container \"backupfiles\".\nIt will use the SAS key \"sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" to gain access to the container.\n\n## PARAMETERS\n\n### -AccountId\nStorage Account Name / Storage Account Id where file information should be retrieved from\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:AzureStorageAccountId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AccessToken\nThe token that has the needed permissions for the search action\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:AzureStorageAccessToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SAS\nThe SAS key for the storage account or blob container\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:AzureStorageSAS\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Container\nName of the blob container inside the storage account where file information should be retrieved from\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Blobname, Blob\n\nRequired: False\nPosition: Named\nDefault value: $Script:AzureStorageContainer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Name\nName of the files information should be retrieved for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"Application*Adaptor\"\n\nDefault value is \"*\" which will search for all files\n\n```yaml\nType: String\nParameter Sets: Default\nAliases: FileName\n\nRequired: False\nPosition: Named\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Latest\nInstruct the cmdlet to only fetch the information of the latest file from the Azure Storage Account\n\n```yaml\nType: SwitchParameter\nParameter Sets: Latest\nAliases: GetLatest\n\nRequired: True\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Azure, Azure Storage, Token, Blob, File, Container\n\nAuthor: Mötz Jensen (@Splaxi)\nAuthor: Florian Hopfner (@FH-Inway)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365AzureStorageUrl.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365AzureStorageUrl\n\n## SYNOPSIS\nGet a blob Url from Azure Storage account\n\n## SYNTAX\n\n```\nGet-D365AzureStorageUrl [[-AccountId] <String>] [[-SAS] <String>] [[-Container] <String>] [-OutputAsHashtable]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet a valid blob container url from an Azure Storage Account\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365AzureStorageUrl -AccountId \"miscfiles\" -SAS \"sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" -Container \"backupfiles\"\n```\n\nThis will generate a valid Url for the blob container in the Azure Storage Account.\nIt will use the AccountId \"miscfiles\" as the name of the storage account.\nIt will use the SAS key \"sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" to add the SAS token/key to the Url.\nIt will use the Container \"backupfiles\" as the container name in the Url.\n\n### EXAMPLE 2\n```\nGet-D365AzureStorageUrl\n```\n\nThis will generate a valid Url for the blob container in the Azure Storage Account.\nIt will use the default values that are configured using the Set-D365ActiveAzureStorageConfig cmdlet and view using the Get-D365ActiveAzureStorageConfig cmdlet.\n\n### EXAMPLE 3\n```\nGet-D365AzureStorageUrl -OutputAsHashtable\n```\n\nThis will generate a valid Url for the blob container in the Azure Storage Account.\nIt will use the default values that are configured using the Set-D365ActiveAzureStorageConfig cmdlet and view using the Get-D365ActiveAzureStorageConfig cmdlet.\n\nThe output object will be a Hashtable, which you can use as a parameter for other cmdlets.\n\n### EXAMPLE 4\n```\n$DestinationParms = Get-D365AzureStorageUrl -OutputAsHashtable\n```\n\nPS C:\\\\\\> $BlobFileDetails = Get-D365LcsDatabaseBackups -Latest | Invoke-D365AzCopyTransfer @DestinationParms\nPS C:\\\\\\> $BlobFileDetails | Invoke-D365AzCopyTransfer -DestinationUri \"C:\\Temp\" -DeleteOnTransferComplete\n\nThis will transfer the lastest backup file from LCS Asset Library to your local \"C:\\Temp\".\nIt will get a destination Url, for it to transfer the backup file between the LCS storage account and your own.\nThe newly transfered file, that lives in your own storage account, will then be downloaded to your local \"c:\\Temp\".\n\nAfter the file has been downloaded to your local \"C:\\Temp\", it will be deleted from your own storage account.\n\n## PARAMETERS\n\n### -AccountId\nStorage Account Name / Storage Account Id you want to work against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:AzureStorageAccountId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SAS\nThe SAS key that you have created for the storage account or blob container\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:AzureStorageSAS\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Container\nName of the blob container inside the storage account you want to work against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Blobname, Blob\n\nRequired: False\nPosition: 3\nDefault value: $Script:AzureStorageContainer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputAsHashtable\nInstruct the cmdlet to return a hastable object\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Azure, Azure Storage, Token, Blob, File, Container, LCS, Asset, Bacpac, Backup\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365BacpacSqlOptions.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365BacpacSqlOptions\n\n## SYNOPSIS\nGet the SQL Server options from the bacpac model.xml file\n\n## SYNTAX\n\n```\nGet-D365BacpacSqlOptions [[-Path] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nExtract the SQL Server options that are listed inside the model.xml file originating from a bacpac file\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365BacpacSqlOptions -Path \"c:\\temp\\d365fo.tools\\bacpac.model.xml\"\n```\n\nThis will display all the SQL Server options configured in the bacpac model file.\n\n### EXAMPLE 2\n```\nExport-D365BacpacModelFile -Path \"c:\\Temp\\AxDB.bacpac\" | Get-D365BacpacSqlOptions\n```\n\nThis will display all the SQL Server options configured in the bacpac file.\nFirst it will export the model.xml from the \"c:\\Temp\\AxDB.bacpac\" file, using the Export-D365BacpacModelFile function.\nThe output from Export-D365BacpacModelFile will be piped into the Get-D365BacpacSqlOptions function.\n\n## PARAMETERS\n\n### -Path\nPath to the extracted model.xml file that you want to work against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File, ModelFile\n\nRequired: False\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Bacpac, Servicing, Data, SqlPackage, Sql Server Options, Collation\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365BacpacTable.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365BacpacTable\n\n## SYNOPSIS\nGet tables from the bacpac file\n\n## SYNTAX\n\n### Default (Default)\n```\nGet-D365BacpacTable -Path <String> [-Table <String[]>] [-Top <Int32>] [<CommonParameters>]\n```\n\n### SortSizeAsc\n```\nGet-D365BacpacTable -Path <String> [-Table <String[]>] [-Top <Int32>] [-SortSizeAsc] [<CommonParameters>]\n```\n\n### SortSizeDesc\n```\nGet-D365BacpacTable -Path <String> [-Table <String[]>] [-Top <Int32>] [-SortSizeDesc] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet tables and their metadata from the bacpac file\n\nMetadata as in original size and compressed size, which are what size the bulk files are and will only indicate what you can expect of the table size\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365BacpacTable -Path \"c:\\Temp\\AxDB.bacpac\"\n```\n\nThis will return all tables from inside the bacpac file.\n\nIt uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\nIt uses the default value \"*\" as the Table parameter, to output all tables.\nIt uses the default value \"\\[int\\]::max\" as the Top parameter, to output all tables.\nIt uses the default sort, which is by name acsending.\n\nA result set example:\n\nName                                                                   OriginalSize CompressedSize BulkFiles\n----                                                                   ------------ -------------- ---------\nax.DBVERSION                                                                   62 B           52 B         1\ncrt.RETAILUPGRADEHISTORY                                                   13,49 MB       13,41 MB         3\ndbo.__AOSMESSAGEREGISTRATION                                                1,80 KB          540 B         2\ndbo.__AOSSTARTUPVERSION                                                         4 B            6 B         1\ndbo.ACCOUNTINGDISTRIBUTION                                                 48,60 MB        4,50 MB        95\ndbo.ACCOUNTINGEVENT                                                        11,16 MB        1,51 MB       128\ndbo.AGREEMENTPARAMETERS_RU                                                    366 B          113 B         1\ndbo.AIFSQLCDCENABLEDTABLES                                                 13,63 KB        2,19 KB         1\ndbo.AIFSQLCHANGETRACKINGENABLEDTABLES                                       9,89 KB        1,42 KB         1\ndbo.AIFSQLCTTRIGGERS                                                       44,75 KB        6,29 KB         1\n\n### EXAMPLE 2\n```\nGet-D365BacpacTable -Path \"c:\\Temp\\AxDB.bacpac\" -SortSizeAsc\n```\n\nThis will return all tables from inside the bacpac file, sorted by the original size, ascending.\n\nIt uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\nIt uses the default value \"*\" as the Table parameter, to output all tables.\nIt uses the default value \"\\[int\\]::max\" as the Top parameter, to output all tables.\nIt uses the SortSizeAsc parameter, which is by original size acsending.\n\nA result set example:\n\nName                                                                   OriginalSize CompressedSize BulkFiles\n----                                                                   ------------ -------------- ---------\ndbo.__AOSSTARTUPVERSION                                                         4 B            6 B         1\ndbo.SYSSORTORDER                                                               20 B           20 B         1\ndbo.SECURITYDATABASESETTINGS                                                   20 B           12 B         1\ndbo.SYSPOLICYSEQUENCEGROUP                                                     24 B           10 B         1\ndbo.SYSFILESTOREPARAMETERS                                                     26 B           10 B         1\ndbo.SYSHELPCPSSETUP                                                            28 B           15 B         1\ndbo.DATABASELOGPARAMETERS                                                      28 B           10 B         1\ndbo.FEATUREMANAGEMENTPARAMETERS                                                28 B           10 B         1\ndbo.AIFSQLCTVERSION                                                            28 B           24 B         1\ndbo.SYSHELPSETUP                                                               28 B           15 B         1\n\n### EXAMPLE 3\n```\nGet-D365BacpacTable -Path \"c:\\Temp\\AxDB.bacpac\" -SortSizeDesc\n```\n\nThis will return all tables from inside the bacpac file, sorted by the original size, descending.\n\nIt uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\nIt uses the default value \"*\" as the Table parameter, to output all tables.\nIt uses the default value \"\\[int\\]::max\" as the Top parameter, to output all tables.\nIt uses the SortSizeDesc parameter, which is by original size descending.\n\nA result set example:\n\nName                                                                   OriginalSize CompressedSize BulkFiles\n----                                                                   ------------ -------------- ---------\ndbo.TSTIMESHEETLINESTAGING                                                 35,31 GB        2,44 GB      9077\ndbo.RESROLLUP                                                              13,30 GB      367,19 MB      3450\ndbo.PROJECTSTAGING                                                         11,31 GB      508,70 MB      2929\ndbo.TSTIMESHEETTABLESTAGING                                                 5,93 GB      246,65 MB      1564\ndbo.BATCHHISTORY                                                            5,80 GB      234,99 MB      1529\ndbo.HCMPOSITIONHIERARCHYSTAGING                                             5,16 GB      222,18 MB      1358\ndbo.ERLCSFILEASSETTABLE                                                     3,15 GB      217,68 MB       302\ndbo.EVENTINBOX                                                              2,92 GB      105,63 MB       747\ndbo.HCMPOSITIONV2STAGING                                                    2,79 GB      200,27 MB       755\ndbo.HCMEMPLOYEESTAGING                                                      2,49 GB      218,69 MB       677\n\n### EXAMPLE 4\n```\nGet-D365BacpacTable -Path \"c:\\Temp\\AxDB.bacpac\" -SortSizeDesc -Top 5\n```\n\nThis will return all tables from inside the bacpac file, sorted by the original size, descending.\n\nIt uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\nIt uses the default value \"*\" as the Table parameter, to output all tables.\nIt uses the value 5 as the Top parameter, to output only 5 tables, based on the sorting selected.\nIt uses the SortSizeDesc parameter, which is by original size descending.\n\nA result set example:\n\nName                                                                   OriginalSize CompressedSize BulkFiles\n----                                                                   ------------ -------------- ---------\ndbo.TSTIMESHEETLINESTAGING                                                 35,31 GB        2,44 GB      9077\ndbo.RESROLLUP                                                              13,30 GB      367,19 MB      3450\ndbo.PROJECTSTAGING                                                         11,31 GB      508,70 MB      2929\ndbo.TSTIMESHEETTABLESTAGING                                                 5,93 GB      246,65 MB      1564\ndbo.BATCHHISTORY                                                            5,80 GB      234,99 MB      1529\n\n### EXAMPLE 5\n```\nGet-D365BacpacTable -Path \"c:\\Temp\\AxDB.bacpac\" -Table \"Sales*\"\n```\n\nThis will return all tables which matches the \"Sales*\" wildcard search from inside the bacpac file.\n\nIt uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\nIt uses the default value \"Sales*\" as the Table parameter, to output all tables that matches the wildcard pattern.\nIt uses the default value \"\\[int\\]::max\" as the Top parameter, to output all tables.\nIt uses the default sort, which is by name acsending.\n\nA result set example:\n\nName                                                                   OriginalSize CompressedSize BulkFiles\n----                                                                   ------------ -------------- ---------\ndbo.SALESPARAMETERS                                                         4,29 KB          310 B         1\ndbo.SALESPARMUPDATE                                                       273,48 KB       24,21 KB         1\ndbo.SALESQUOTATIONTOLINEPARAMETERS                                          4,18 KB          596 B         1\ndbo.SALESSUMMARYPARAMETERS                                                  2,95 KB          425 B         1\ndbo.SALESTABLE                                                              1,20 KB          313 B         1\ndbo.SALESTABLE_W                                                              224 B           60 B         1\ndbo.SALESTABLE2LINEPARAMETERS                                               4,46 KB          637 B         1\n\n### EXAMPLE 6\n```\nGet-D365BacpacTable -Path \"c:\\Temp\\AxDB.bacpac\" -Table \"Sales*\",\"CUSTINVOICE*\"\n```\n\nThis will return all tables which matches the \"Sales*\" and \"CUSTINVOICE*\" wildcard searches from inside the bacpac file.\n\nIt uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\nIt uses the default value \"Sales*\" and \"CUSTINVOICE*\" as the Table parameter, to output all tables that matches the wildcard pattern.\nIt uses the default value \"\\[int\\]::max\" as the Top parameter, to output all tables.\nIt uses the default sort, which is by name acsending.\n\nA result set example:\n\nName                                                                   OriginalSize CompressedSize BulkFiles\n----                                                                   ------------ -------------- ---------\ndbo.CUSTINVOICEJOUR                                                         2,01 MB      118,87 KB         1\ndbo.CUSTINVOICELINE                                                        14,64 MB      975,30 KB         4\ndbo.CUSTINVOICELINEINTERPROJ                                                6,58 MB      477,97 KB         2\ndbo.CUSTINVOICETABLE                                                        1,06 MB       56,56 KB         1\ndbo.CUSTINVOICETRANS                                                       32,34 MB        1,51 MB        54\ndbo.SALESPARAMETERS                                                         4,29 KB          310 B         1\ndbo.SALESPARMUPDATE                                                       273,48 KB       24,21 KB         1\ndbo.SALESQUOTATIONTOLINEPARAMETERS                                          4,18 KB          596 B         1\ndbo.SALESSUMMARYPARAMETERS                                                  2,95 KB          425 B         1\ndbo.SALESTABLE                                                              1,20 KB          313 B         1\ndbo.SALESTABLE_W                                                              224 B           60 B         1\ndbo.SALESTABLE2LINEPARAMETERS                                               4,46 KB          637 B         1\n\n### EXAMPLE 7\n```\nGet-D365BacpacTable -Path \"c:\\Temp\\AxDB.bacpac\" -Table \"SalesTable\",\"CustTable\"\n```\n\nThis will return the tables \"dbo.SalesTable\" and \"dbo.CustTable\" from inside the bacpac file.\n\nIt uses \"c:\\Temp\\AxDB.bacpac\" as the Path for the bacpac file.\nIt uses the default value \"SalesTable\" and \"CustTable\" as the Table parameter, to output the tables that matches the names.\nIt uses the default value \"\\[int\\]::max\" as the Top parameter, to output all tables.\nIt uses the default sort, which is by name acsending.\n\nA result set example:\n\nName                                                                   OriginalSize CompressedSize BulkFiles\n----                                                                   ------------ -------------- ---------\ndbo.CUSTTABLE                                                             154,91 KB        8,26 KB         1\ndbo.SALESTABLE                                                              1,20 KB          313 B         1\n\n## PARAMETERS\n\n### -Path\nPath to the bacpac file that you want to work against\n\nIt can also be a zip file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: BacpacFile, File\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Table\nName of the table that you want to delete the data for\n\nSupports an array of table names\n\nIf a schema name isn't supplied as part of the table name, the cmdlet will prefix it with \"dbo.\"\n\nSupports wildcard searching e.g.\n\"Sales*\" will locate all \"dbo.Sales*\" tables in the bacpac file\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Top\nInstruct the cmdlet with how many tables you want returned\n\nDefault is \\[int\\]::max, which translates into all tables present inside the bapcac file\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: 2147483647\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SortSizeAsc\nInstruct the cmdlet to sort the output by size (original) ascending\n\n```yaml\nType: SwitchParameter\nParameter Sets: SortSizeAsc\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SortSizeDesc\nInstruct the cmdlet to sort the output by size (original) descending\n\n```yaml\nType: SwitchParameter\nParameter Sets: SortSizeDesc\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Bacpac, Servicing, Data, SqlPackage, Table, Size, Troubleshooting\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365BroadcastMessage.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365BroadcastMessage\n\n## SYNOPSIS\nGet broadcast message from the D365FO environment\n\n## SYNTAX\n\n```\nGet-D365BroadcastMessage [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>]\n [[-SqlPwd] <String>] [-ExcludeExpired] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet broadcast message from the D365FO environment by looking into the database table\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365BroadcastMessage\n```\n\nThis will display all the broadcast message records from the SysBroadcastMessage table.\n\n### EXAMPLE 2\n```\nGet-D365BroadcastMessage -ExcludeExpired\n```\n\nThis will display all active the broadcast message records from the SysBroadcastMessage table.\n\n## PARAMETERS\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ExcludeExpired\nExclude all the records that has already expired\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Broadcast, Message, SysBroadcastMessage, Servicing, Message, Users, Environment\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365BroadcastMessageConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365BroadcastMessageConfig\n\n## SYNOPSIS\nGet broadcast message configs\n\n## SYNTAX\n\n```\nGet-D365BroadcastMessageConfig [[-Name] <String>] [-OutputAsHashtable] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet all broadcast message configuration objects from the configuration store\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365BroadcastMessageConfig\n```\n\nThis will display all broadcast message configurations on the machine.\n\n### EXAMPLE 2\n```\nGet-D365BroadcastMessageConfig -OutputAsHashtable\n```\n\nThis will display all broadcast message configurations on the machine.\nEvery object will be output as a hashtable, for you to utilize as parameters for other cmdlets.\n\n### EXAMPLE 3\n```\nGet-D365BroadcastMessageConfig -Name \"UAT\"\n```\n\nThis will display the broadcast message configuration that is saved with the name \"UAT\" on the machine.\n\n## PARAMETERS\n\n### -Name\nThe name of the broadcast message configuration you are looking for\n\nDefault value is \"*\" to display all broadcast message configs\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputAsHashtable\nInstruct the cmdlet to return a hastable object\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### PSCustomObject\n## NOTES\nTags: Servicing, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Add-D365BroadcastMessageConfig]()\n\n[Clear-D365ActiveBroadcastMessageConfig]()\n\n[Get-D365ActiveBroadcastMessageConfig]()\n\n[Remove-D365BroadcastMessageConfig]()\n\n[Send-D365BroadcastMessage]()\n\n[Set-D365ActiveBroadcastMessageConfig]()\n\n"
  },
  {
    "path": "docs/Get-D365ClickOnceTrustPrompt.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365ClickOnceTrustPrompt\n\n## SYNOPSIS\nGet the ClickOnce configuration\n\n## SYNTAX\n\n```\nGet-D365ClickOnceTrustPrompt [<CommonParameters>]\n```\n\n## DESCRIPTION\nCreates the needed registry keys and values for ClickOnce to work on the machine\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365ClickOnceTrustPrompt\n```\n\nThis will get the current ClickOnce configuration\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: ClickOnce, Registry, TrustPrompt\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365CompilerResult.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365CompilerResult\n\n## SYNOPSIS\nGet the compiler outputs presented\n\n## SYNTAX\n\n```\nGet-D365CompilerResult [-Path] <String> [-ErrorsOnly] [-OutputTotals] [-OutputAsObjects] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the compiler outputs presented in a structured manner on the screen\n\nIt could be a Visual Studio compiler log or it could be a Invoke-D365ModuleCompile log you want analyzed\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365CompilerResult -Path \"c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log\"\n```\n\nThis will analyze the compiler log file for warning and errors.\n\nA result set example:\n\nFile                                                                                    Warnings Errors\n----                                                                                    -------- ------\nc:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log                                        2      1\n\n### EXAMPLE 2\n```\nGet-D365CompilerResult -Path \"c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log\" -ErrorsOnly\n```\n\nThis will analyze the compiler log file for warning and errors, but only output if it has errors.\n\nA result set example:\n\nFile                                                                                    Warnings Errors\n----                                                                                    -------- ------\nc:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log                                        2      1\n\n### EXAMPLE 3\n```\nGet-D365CompilerResult -Path \"c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log\" -ErrorsOnly -OutputAsObjects\n```\n\nThis will analyze the compiler log file for warning and errors, but only output if it has errors.\nThe output will be PSObjects, which can be assigned to a variable and used for futher analysis.\n\nA result set example:\n\nFile                                                                                    Warnings Errors\n----                                                                                    -------- ------\nc:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log                                        2      1\n\n### EXAMPLE 4\n```\nGet-D365Module -Name *Custom* | Invoke-D365ModuleCompile | Get-D365CompilerResult -OutputTotals\n```\n\nThis will find all modules with Custom in their name.\nIt will pass thoses modules into the Invoke-D365ModuleCompile, which will compile them.\nIt will pass the paths to each compile output log to Get-D365CompilerResult, which will analyze them for warning and errors.\nIt will output the total number of warning and errors found.\n\nFile                                                                                    Warnings Errors\n----                                                                                    -------- ------\nc:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log                                        2      1\n\nTotal Errors: 1\nTotal Warnings: 2\n\n## PARAMETERS\n\n### -Path\nPath to the compiler log file that you want to work against\n\nA BuildModelResult.log or a Dynamics.AX.*.xppc.log file will both work\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogFile\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### -ErrorsOnly\nInstructs the cmdlet to only output compile results where there was errors detected\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputTotals\nInstructs the cmdlet to output the total errors and warnings after the analysis\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputAsObjects\nInstructs the cmdlet to output the objects instead of formatting them\n\nIf you don't assign the output, it will be formatted the same way as the original output, but without the coloring of the column values\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### [PsCustomObject]\n## NOTES\nTags: Compiler, Build, Errors, Warnings, Tasks\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThis cmdlet is inspired by the work of \"Vilmos Kintera\" (twitter: @DAXRunBase)\n\nAll credits goes to him for showing how to extract these information\n\nHis blog can be found here:\nhttps://www.daxrunbase.com/blog/\n\nThe specific blog post that we based this cmdlet on can be found here:\nhttps://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/\n\nThe github repository containing the original scrips can be found here:\nhttps://github.com/DAXRunBase/PowerShell-and-Azure\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365Database.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365Database\n\n## SYNOPSIS\nGet databases from the server\n\n## SYNTAX\n\n```\nGet-D365Database [[-Name] <String[]>] [[-DatabaseServer] <String>] [[-DatabaseName] <String>]\n [[-SqlUser] <String>] [[-SqlPwd] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the names of databases on either SQL Server or in Azure SQL Database instance\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365Database\n```\n\nThis will show all databases on the default SQL Server / Azure SQL Database instance.\n\n### EXAMPLE 2\n```\nGet-D365Database -Name AXDB_ORIGINAL\n```\n\nThis will show if the AXDB_ORIGINAL database exists on the default SQL Server / Azure SQL Database instance.\n\n## PARAMETERS\n\n### -Name\nName of the database that you are looking for\n\nDefault value is \"*\" which will show all databases\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### [PsCustomObject]\n## NOTES\nTags: Database, DB, Servicing\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365DatabaseAccess.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365DatabaseAccess\n\n## SYNOPSIS\nShows the Database Access information for the D365 Environment\n\n## SYNTAX\n\n```\nGet-D365DatabaseAccess [<CommonParameters>]\n```\n\n## DESCRIPTION\nGets all database information from the D365 environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365DatabaseAccess\n```\n\nThis will get all relevant details, including connection details, for the database configured for the environment\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Database, Connection, Sql, SqlUser, SqlPwd\n\nAuthor: Rasmus Andersen (@ITRasmus)\n\nThe cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations.\nThe call to the dll file gets all relevant connections details for the database server.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365DecryptedWebConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365DecryptedWebConfig\n\n## SYNOPSIS\nDecrypts the AOS config file\n\n## SYNTAX\n\n```\nGet-D365DecryptedWebConfig [[-OutputPath] <String>] [[-AosServiceWebRootPath] <String>]\n```\n\n## DESCRIPTION\nFunction used for decrypting the config file used by the D365 Finance & Operations AOS service\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365DecryptedWebConfig\n```\n\nThis will get the config file from the instance, decrypt it and save it.\nIT will save the decrypted web.config file in the default location: \"c:\\temp\\d365fo.tools\\WebConfigDecrypted\".\n\nA result set example:\n\nFilename   LastModified        File\n--------   ------------        ----\nweb.config 7/1/2021 9:01:31 PM C:\\temp\\d365fo.tools\\WebConfigDecrypted\\web.config\n\n### EXAMPLE 2\n```\nGet-D365DecryptedWebConfig -OutputPath \"c:\\temp\\d365fo.tools\"\n```\n\nThis will get the config file from the instance, decrypt it and save it to \"c:\\temp\\d365fo.tools\"\n\nA result set example:\n\nFilename   LastModified        File\n--------   ------------        ----\nweb.config 7/1/2021 9:07:36 PM C:\\temp\\d365fo.tools\\web.config\n\n## PARAMETERS\n\n### -OutputPath\nPlace where the decrypted files should be placed\n\nDefault value is: \"c:\\temp\\d365fo.tools\\WebConfigDecrypted\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: C:\\temp\\d365fo.tools\\WebConfigDecrypted\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AosServiceWebRootPath\nLocation of the D365 webroot folder\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:AOSPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Configuration, Service Account, Sql, SqlUser, SqlPwd, WebConfig, Web.Config, Decryption\n\nAuthor : Rasmus Andersen (@ITRasmus)\nAuthor : Mötz Jensen (@splaxi)\n\nUsed for getting the Password for the database and other service accounts used in environment\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365DefaultModelForNewProjects.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365DefaultModelForNewProjects\n\n## SYNOPSIS\nGet the default model used creating new projects in Visual Studio\n\n## SYNTAX\n\n```\nGet-D365DefaultModelForNewProjects [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the registered default model that is used across all new projects that are created inside Visual Studio when working with D365FO project types\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365DefaultModelForNewProjects\n```\n\nThis will display the current default module registered in the \"DynamicsDevConfig.xml\" file.\nLocated in Documents\\Visual Studio Dynamics 365\\ or in Documents\\Visual Studio 2015\\Settings\\ depending on the version.\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTag: Model, Models, Development, Default Model, Module, Project\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThe work for this cmdlet / function was inspired by Robin Kretzschmar (@DarkSmile92) blog post about changing the default model.\n\nThe direct link for his blog post is: https://robscode.onl/d365-set-default-model-for-new-projects/\n\nHis main blog can found here: https://robscode.onl/\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365DotNetClass.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365DotNetClass\n\n## SYNOPSIS\nGet a .NET class from the Dynamics 365 for Finance and Operations installation\n\n## SYNTAX\n\n```\nGet-D365DotNetClass [[-Name] <String>] [[-Assembly] <String>] [[-PackageDirectory] <String>]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet a .NET class from an assembly file (dll) from the package directory\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365DotNetClass -Name \"ERText*\"\n```\n\nWill search across all assembly files (*.dll) that are located in the default package directory after\nany class that fits the search \"ERText*\"\n\n### EXAMPLE 2\n```\nGet-D365DotNetClass -Name \"ERText*\" -Assembly \"*LocalizationFrameworkForAx.dll*\"\n```\n\nWill search across all assembly files (*.dll) that are fits the search \"*LocalizationFrameworkForAx.dll*\",\nthat are located in the default package directory, after any class that fits the search \"ERText*\"\n\n### EXAMPLE 3\n```\nGet-D365DotNetClass -Name \"ERText*\" | Export-Csv -Path c:\\temp\\results.txt -Delimiter \";\"\n```\n\nWill search across all assembly files (*.dll) that are located in the default package directory after\nany class that fits the search \"ERText*\"\n\nThe output is saved to a file to make it easier to search inside the result set\n\n## PARAMETERS\n\n### -Name\nName of the .NET class that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"ER*Excel*\"\n\nDefault value is \"*\" which will search for all classes\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Assembly\nName of the assembly file that you want to search for the .NET class\n\nAccepts wildcards for searching.\nE.g.\n-Name \"*AX*Framework*.dll\"\n\nDefault value is \"*.dll\" which will search for assembly files\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: *.dll\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed packages\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: .Net, DotNet, Class, Development\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThe cmdlet supports piping and can be used in advanced scenarios.\nSee more on github and the wiki pages.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365DotNetMethod.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365DotNetMethod\n\n## SYNOPSIS\nGet a .NET method from the Dynamics 365 for Finance and Operations installation\n\n## SYNTAX\n\n```\nGet-D365DotNetMethod [-Assembly] <String> [[-Name] <String>] [[-TypeName] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet a .NET method from an assembly file (dll) from the package directory\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365DotNetMethod -Assembly \"C:\\AOSService\\PackagesLocalDirectory\\ElectronicReporting\\bin\\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll\"\n```\n\nWill get all methods, across all classes, from the assembly file\n\n### EXAMPLE 2\n```\nGet-D365DotNetMethod -Assembly \"C:\\AOSService\\PackagesLocalDirectory\\ElectronicReporting\\bin\\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll\" -TypeName \"ERTextFormatExcelFileComponent\"\n```\n\nWill get all methods, from the \"ERTextFormatExcelFileComponent\" class, from the assembly file\n\n### EXAMPLE 3\n```\nGet-D365DotNetMethod -Assembly \"C:\\AOSService\\PackagesLocalDirectory\\ElectronicReporting\\bin\\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll\" -TypeName \"ERTextFormatExcelFileComponent\" -Name \"*parm*\"\n```\n\nWill get all methods that fits the search \"*parm*\", from the \"ERTextFormatExcelFileComponent\" class, from the assembly file\n\n### EXAMPLE 4\n```\nGet-D365DotNetClass -Name \"ERTextFormatExcelFileComponent\" -Assembly \"*LocalizationFrameworkForAx.dll*\" | Get-D365DotNetMethod\n```\n\nWill get all methods, from the \"ERTextFormatExcelFileComponent\" class, from any assembly file that fits the search \"*LocalizationFrameworkForAx.dll*\"\n\n## PARAMETERS\n\n### -Assembly\nName of the assembly file that you want to search for the .NET method\n\nProvide the full path for the assembly file you want to work against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Name\nName of the .NET method that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"parmER*Excel*\"\n\nDefault value is \"*\" which will search for all methods\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: MethodName\n\nRequired: False\nPosition: 3\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -TypeName\nName of the .NET class that you want to work against\n\nAccepts wildcards for searching.\nE.g.\n-Name \"*ER*Excel*\"\n\nDefault value is \"*\" which will work against all classes\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: ClassName\n\nRequired: False\nPosition: 4\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: .Net, DotNet, Class, Method, Methods, Development\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThe cmdlet supports piping and can be used in advanced scenarios.\nSee more on github and the wiki pages.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365Environment.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365Environment\n\n## SYNOPSIS\nCmdlet to get the current status for the different services in a Dynamics 365 Finance & Operations environment\n\n## SYNTAX\n\n### Default (Default)\n```\nGet-D365Environment [[-ComputerName] <String[]>] [-All] [-OnlyStartTypeAutomatic] [-OutputServiceDetailsOnly]\n [<CommonParameters>]\n```\n\n### Specific\n```\nGet-D365Environment [[-ComputerName] <String[]>] [-Aos] [-Batch] [-FinancialReporter] [-DMF]\n [-OnlyStartTypeAutomatic] [-OutputServiceDetailsOnly] [<CommonParameters>]\n```\n\n## DESCRIPTION\nList status for all relevant services that is running in a D365FO environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365Environment\n```\n\nWill query all D365FO service on the machine.\n\n### EXAMPLE 2\n```\nGet-D365Environment -All\n```\n\nWill query all D365FO service on the machine.\n\n### EXAMPLE 3\n```\nGet-D365Environment -OnlyStartTypeAutomatic\n```\n\nWill query all D365FO service on the machine.\nIt will filter out all services that are either configured as manual or disabled.\n\n### EXAMPLE 4\n```\nGet-D365Environment -ComputerName \"TEST-SB-AOS1\",\"TEST-SB-AOS2\",\"TEST-SB-BI1\" -All\n```\n\nWill query all D365FO service on the different machines.\n\n### EXAMPLE 5\n```\nGet-D365Environment -Aos -Batch\n```\n\nWill query the Aos & Batch services on the machine.\n\n### EXAMPLE 6\n```\nGet-D365Environment -FinancialReporter -DMF\n```\n\nWill query the FinancialReporter & DMF services on the machine.\n\n### EXAMPLE 7\n```\nGet-D365Environment -OutputServiceDetailsOnly\n```\n\nWill query all D365FO service on the machine.\nWill omit the servername from the output.\n\n### EXAMPLE 8\n```\nGet-D365Environment -FinancialReporter | Set-Service -StartupType Manual\n```\n\nThis will configure the Financial Reporter services to be start type manual.\n\n## PARAMETERS\n\n### -ComputerName\nAn array of computers that you want to query for the services status on.\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: @($env:computername)\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -All\nSet when you want to query all relevant services\n\nIncludes:\nAos\nBatch\nFinancial Reporter\nDMF\n\n```yaml\nType: SwitchParameter\nParameter Sets: Default\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: True\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Aos\nInstruct the cmdlet to query the AOS (IIS) service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Batch\nInstruct the cmdlet query the batch service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FinancialReporter\nInstruct the cmdlet query the financial reporter (Management Reporter 2012)\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DMF\nInstruct the cmdlet query the DMF service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OnlyStartTypeAutomatic\nInstruct the cmdlet to filter out services that are set to manual start or disabled\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputServiceDetailsOnly\nInstruct the cmdlet to exclude the server name from the output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Environment, Service, Services, Aos, Batch, Servicing\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365EnvironmentSettings.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365EnvironmentSettings\n\n## SYNOPSIS\nGet the D365FO environment settings\n\n## SYNTAX\n\n```\nGet-D365EnvironmentSettings [<CommonParameters>]\n```\n\n## DESCRIPTION\nGets all settings the Dynamics 365 for Finance & Operations environment uses.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365EnvironmentSettings\n```\n\nThis will get all details available for the environment\n\n### EXAMPLE 2\n```\nGet-D365EnvironmentSettings | Format-Custom -Property *\n```\n\nThis will get all details available for the environment and format it to show all details in a long custom object.\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Environment, Configuration, WebConfig, Web.Config, Decryption\n\nAuthor: Rasmus Andersen (@ITRasmus)\nAuthor: Mötz Jensen (@Splaxi)\n\nThe cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations.\nThe call to the dll file gets all relevant details for the installation.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365EventTraceProvider.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365EventTraceProvider\n\n## SYNOPSIS\nGet D365FO Event Trace Provider\n\n## SYNTAX\n\n```\nGet-D365EventTraceProvider [[-Name] <String[]>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the full list of available Event Trace Providers for Dynamics 365 for Finance and Operations\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365EventTraceProvider\n```\n\nWill list all available Event Trace Providers on a D365FO server.\nIt will use the default option for the \"Name\" parameter.\n\n### EXAMPLE 2\n```\nGet-D365EventTraceProvider -Name Tax\n```\n\nWill list all available Event Trace Providers on a D365FO server which contains the keyvword \"Tax\".\nIt will use the Name parameter value \"Tax\" while searching for Event Trace Providers.\n\n### EXAMPLE 3\n```\nGet-D365EventTraceProvider -Name Tax,MR\n```\n\nWill list all available Event Trace Providers on a D365FO server which contains the keyvword \"Tax\" or \"MR\".\nIt will use the Name parameter array value (\"Tax\",\"MR\") while searching for Event Trace Providers.\n\n## PARAMETERS\n\n### -Name\nName of the provider that you are looking for\n\nDefault value is \"*\" to show all Event Trace Providers\n\nAccepts an array of names, and will automatically add wildcard searching characters for each entry\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: @(\"*\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: ETL, EventTracing, EventTrace\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThis cmdlet/function was inspired by the work of Michael Stashwick (@D365Stuff)\n\nHe blog is located here: https://www.d365stuff.co/\n\nand the blogpost that pointed us in the right direction is located here: https://www.d365stuff.co/trace-batch-jobs-and-more-via-cmd-logman/\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365ExternalIP.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365ExternalIP\n\n## SYNOPSIS\nGet the external IP address\n\n## SYNTAX\n\n```\nGet-D365ExternalIP [-SaveToClipboard] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the external IP address by calling an external webpage and interpret the result from that\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365ExternalIP\n```\n\nWill call the external page, interpret the output and display it as output.\n\nA result set example:\n\nIpAddress\n---------\n40.113.130.229\n\n### EXAMPLE 2\n```\nGet-D365ExternalIP -SaveToClipboard\n```\n\nWill call the external page, interpret the output and display it as output.\nIt will save/copy the IP address into the clipboard.\n\nA result set example:\n\nIpAddress\n---------\n40.113.130.229\n\n## PARAMETERS\n\n### -SaveToClipboard\nInstruct the cmdlet to copy the IP address directly into the clipboard, to save you the trouble\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: DEV, Tier2, DB, Database, Debug, JIT, LCS, Azure DB, IP\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365Flight.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365Flight\n\n## SYNOPSIS\nUsed to get a flight\n\n## SYNTAX\n\n```\nGet-D365Flight [[-FlightName] <String>] [[-DatabaseServer] <String>] [[-DatabaseName] <String>]\n [[-SqlUser] <String>] [[-SqlPwd] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nProvides a method for listing a flight in D365FO.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365Flight\n```\n\nThis will list all flights that are configured on the environment.\nIt will show the name and the enabled status.\n\nA result set example:\n\nFlightName                         Enabled FlightServiceId\n----------                         ------- ---------------\nWHSWorkCancelForcedFlight          1       12719367\nTAMRebateGlobalEnableFeature       1       12719367\nEnablePerfInfoSimpleLoggerV2       1       12719367\nEnablePerfInfoLogODataV2           1       12719367\nEnablePerfInfoLogEtwRequestTableV2 1       12719367\nEnablePerfInfoCursorLayerV2        1       12719367\nEnablePerfInfoFormEngineLayerV2    1       12719367\nEnablePerfInfoMutexWaitLayerV2     1       12719367\nEnablePerfInfoSecurityLayerV2      1       12719367\nEnablePerfInfoSessionLayerV2       1       12719367\nEnablePerfInfoSQLLayerV2           1       12719367\nEnablePerfInfoXppContainerLayerV2  1       12719367\n\n### EXAMPLE 2\n```\nGet-D365Flight -FlightName WHSWorkCancelForcedFlight\n```\n\nThis will list the flight with the specified name on the environment.\nIt will show the name and the enabled status.\n\nA result set example:\n\nFlightName                         Enabled FlightServiceId\n----------                         ------- ---------------\nWHSWorkCancelForcedFlight          1       12719367\n\n### EXAMPLE 3\n```\nGet-D365Flight -FlightName WHS*\n```\n\nThis will list the flight with the specified pattern on the environment.\nIt will filter the output to match the \"WHS*\" pattern.\nIt will show the name and the enabled status.\n\nA result set example:\n\nFlightName                         Enabled FlightServiceId\n----------                         ------- ---------------\nWHSWorkCancelForcedFlight          1       12719367\n\n## PARAMETERS\n\n### -FlightName\nName of the flight that you are looking for\n\nSupports wildcards \"*\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Flight, Flighting\n\nAuthor: Mötz Jensen (@Splaxi)\n\nAt no circumstances can this cmdlet be used to enable a flight in a PROD environment.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365IISPreload.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365IISPreload\n\n## SYNOPSIS\nGets IIS Preload status for the AOSService application pool and website.\n\n## SYNTAX\n\n```\nGet-D365IISPreload [<CommonParameters>]\n```\n\n## DESCRIPTION\nReturns the current IIS Preload configuration for the AOSService application:\n- Application Pool Start Mode\n- Idle Time-out\n- Website Preload Enabled\n- doAppInitAfterRestart (if Application Initialization is installed)\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365IISPreload\n```\n\nRetrieves the IIS Preload configuration for the AOSService application pool and website.\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### System.Management.Automation.PSCustomObject\n### A custom object containing the following properties:\n### - AppPool: Name of the application pool (AOSService)\n### - StartMode: Start mode of the application pool (e.g., AlwaysRunning)\n### - IdleTimeout: Idle timeout of the application pool (e.g., 00:00:00)\n### - Site: Name of the website (AOSService)\n### - PreloadEnabled: Indicates if preload is enabled for the website (True/False)\n### - DoAppInitAfterRestart: Indicates if doAppInitAfterRestart is enabled (if Application Initialization is installed)\n### - PreloadPage: The initialization page configured for preload (if any)\n### - IISApplicationInitFeature: State of the IIS Application Initialization feature (Installed/Not installed)\n## NOTES\nAuthor: Florian Hopfner (FH-Inway)\nBased on Denis Trunin's article \"Enable IIS Preload to Speed Up Restart After X++ Compile\" (https://www.linkedin.com/pulse/enable-iis-preload-speed-up-restart-after-x-compile-denis-trunin-86j5c)\nWritten with GitHub Copilot GPT-4.1, mostly in agent mode.\nSee commits for prompts.\n\n## RELATED LINKS\n\n[Enable-D365IISPreload]()\n\n[Disable-D365IISPreload]()\n\n"
  },
  {
    "path": "docs/Get-D365InstalledHotfix.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365InstalledHotfix\n\n## SYNOPSIS\nGet installed hotfix (DEPRECATED)\n\n## SYNTAX\n\n```\nGet-D365InstalledHotfix [[-BinDir] <String>] [[-PackageDirectory] <String>] [[-Model] <String>]\n [[-Name] <String>] [[-KB] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet all relevant details for installed hotfixes on environments that are not on a \"One Version\" version.\nThis cmdlet is deprecated since 2021-10-05 and will be removed by 2022-04-05.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365InstalledHotfix\n```\n\nThis will display all installed hotfixes found on this machine\n\n### EXAMPLE 2\n```\nGet-D365InstalledHotfix -Model \"*retail*\"\n```\n\nThis will display all installed hotfixes found for all models that matches the search for \"*retail*\" found on this machine\n\n### EXAMPLE 3\n```\nGet-D365InstalledHotfix -Model \"*retail*\" -KB \"*43*\"\n```\n\nThis will display all installed hotfixes found for all models that matches the search for \"*retail*\" and only with KB's that matches the search for \"*43*\" found on this machine\n\n## PARAMETERS\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the AOS Service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the PackagesLocalDirectory\n\nDefault path is the same as the AOS Service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Model\nName of the model that you want to work against\n\nAccepts wildcards for searching.\nE.g.\n-Model \"*Retail*\"\n\nDefault value is \"*\" which will search for all models\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Name\nName of the hotfix that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"7045*\"\n\nDefault value is \"*\" which will search for all hotfixes\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -KB\nKB number of the hotfix that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-KB \"4045*\"\n\nDefault value is \"*\" which will search for all KB's\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Hotfix, Servicing, Model, Models, KB, Patch, Patching, PackagesLocalDirectory\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThis cmdlet is inspired by the work of \"Ievgen Miroshnikov\" (twitter: @IevgenMir)\n\nAll credits goes to him for showing how to extract these information\n\nHis blog can be found here:\nhttps://ievgensaxblog.wordpress.com\n\nThe specific blog post that we based this cmdlet on can be found here:\nhttps://ievgensaxblog.wordpress.com/2017/11/17/d365foe-get-list-of-installed-metadata-hotfixes-using-metadata-api/\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365InstalledPackage.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365InstalledPackage\n\n## SYNOPSIS\nGet installed package from Dynamics 365 Finance & Operations environment\n\n## SYNTAX\n\n```\nGet-D365InstalledPackage [[-Name] <String>] [[-PackageDirectory] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet installed package from the machine running the AOS service for Dynamics 365 Finance & Operations\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365InstalledPackage\n```\n\nShows the entire list of installed packages located in the default location on the machine\n\nA result set example:\nApplicationFoundationFormAdaptor\nApplicationPlatformFormAdaptor\nApplicationSuiteFormAdaptor\nApplicationWorkspacesFormAdaptor\n\n### EXAMPLE 2\n```\nGet-D365InstalledPackage -Name \"Application*Adaptor\"\n```\n\nShows the list of installed packages where the name fits the search \"Application*Adaptor\"\n\nA result set example:\nApplicationFoundationFormAdaptor\nApplicationPlatformFormAdaptor\nApplicationSuiteFormAdaptor\nApplicationWorkspacesFormAdaptor\n\n### EXAMPLE 3\n```\nGet-D365InstalledPackage -PackageDirectory \"J:\\AOSService\\PackagesLocalDirectory\"\n```\n\nShows the entire list of installed packages located in \"J:\\AOSService\\PackagesLocalDirectory\" on the machine\n\nA result set example:\nApplicationFoundationFormAdaptor\nApplicationPlatformFormAdaptor\nApplicationSuiteFormAdaptor\nApplicationWorkspacesFormAdaptor\n\n## PARAMETERS\n\n### -Name\nName of the package that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"Application*Adaptor\"\n\nDefault value is \"*\" which will search for all packages\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed packages\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: PackagesLocalDirectory, Servicing, Model, Models, Package, Packages\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThe cmdlet supports piping and can be used in advanced scenarios.\nSee more on github and the wiki pages.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365InstalledService.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365InstalledService\n\n## SYNOPSIS\nGet installed D365 services\n\n## SYNTAX\n\n```\nGet-D365InstalledService [[-Path] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet installed Dynamics 365 for Finance & Operations services that are installed on the machine\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365InstalledService\n```\n\nThis will get all installed services on the machine.\n\n## PARAMETERS\n\n### -Path\nPath to the folder that contains the \"InstallationRecords\" folder\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:InstallationRecordsDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Services, Servicing, Topology\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365InstanceName.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365InstanceName\n\n## SYNOPSIS\nGets the instance name\n\n## SYNTAX\n\n```\nGet-D365InstanceName [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the instance name that is registered in the environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365InstanceName\n```\n\nThis will get the service name that the environment has configured\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Instance, Servicing\n\nAuthor: Rasmus Andersen (@ITRasmus)\n\nThe cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations.\nThe call to the dll file gets HostedServiceName that is registered in the environment.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365JsonService.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365JsonService\n\n## SYNOPSIS\nGet Json based service\n\n## SYNTAX\n\n```\nGet-D365JsonService [[-Name] <String>] [-Url] <String> [-Tenant] <String> [-ClientId] <String>\n [-ClientSecret] <String> [-RawOutput] [-OutputAsJson] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet Json based services that are available from a Dynamics 365 Finance & Operations environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365JsonService -Url \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" -Tenant \"e674da86-7ee5-40a7-b777-1111111111111\" -ClientId \"dea8d7a9-1602-4429-b138-111111111111\" -ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\"\n```\n\nThis will get all available service groups for the D365FO instance.\nIt will contact the D365FO instance specified in the Url parameter: \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\".\nIt will authenticate againt the \"https://login.microsoftonline.com/e674da86-7ee5-40a7-b777-1111111111111/oauth2/token\" url with the specified Tenant parameter: \"e674da86-7ee5-40a7-b777-1111111111111\".\nIt will authenticate with the specified ClientId parameter: \"dea8d7a9-1602-4429-b138-111111111111\".\nIt will authenticate with the specified ClientSecret parameter: \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\".\n\n### EXAMPLE 2\n```\nGet-D365JsonService -Name \"*TS*\" -Url \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" -Tenant \"e674da86-7ee5-40a7-b777-1111111111111\" -ClientId \"dea8d7a9-1602-4429-b138-111111111111\" -ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\"\n```\n\nThis will get all available service groups for the D365FO instance, which matches the \"*TS*\" as a name.\nIt will contact the D365FO instance specified in the Url parameter: \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\".\nIt will authenticate againt the \"https://login.microsoftonline.com/e674da86-7ee5-40a7-b777-1111111111111/oauth2/token\" url with the specified Tenant parameter: \"e674da86-7ee5-40a7-b777-1111111111111\".\nIt will authenticate with the specified ClientId parameter: \"dea8d7a9-1602-4429-b138-111111111111\".\nIt will authenticate with the specified ClientSecret parameter: \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\".\nIt will limit the output to only those matching the specified Name parameter: \"*TS*\"\n\n### EXAMPLE 3\n```\nGet-D365JsonService -Url \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" -Tenant \"e674da86-7ee5-40a7-b777-1111111111111\" -ClientId \"dea8d7a9-1602-4429-b138-111111111111\" -ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\" -RawOutput\n```\n\nThis will get all available service groups for the D365FO instance with the outer most hierarchy.\nIt will contact the D365FO instance specified in the Url parameter: \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\".\nIt will authenticate againt the \"https://login.microsoftonline.com/e674da86-7ee5-40a7-b777-1111111111111/oauth2/token\" url with the specified Tenant parameter: \"e674da86-7ee5-40a7-b777-1111111111111\".\nIt will authenticate with the specified ClientId parameter: \"dea8d7a9-1602-4429-b138-111111111111\".\nIt will authenticate with the specified ClientSecret parameter: \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\".\n\n### EXAMPLE 4\n```\nGet-D365JsonService -Url \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" -Tenant \"e674da86-7ee5-40a7-b777-1111111111111\" -ClientId \"dea8d7a9-1602-4429-b138-111111111111\" -ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\" -OutputAsJson\n```\n\nThis will get all available service groups for the D365FO instance and display the result as json.\nIt will contact the D365FO instance specified in the Url parameter: \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\".\nIt will authenticate againt the \"https://login.microsoftonline.com/e674da86-7ee5-40a7-b777-1111111111111/oauth2/token\" url with the specified Tenant parameter: \"e674da86-7ee5-40a7-b777-1111111111111\".\nIt will authenticate with the specified ClientId parameter: \"dea8d7a9-1602-4429-b138-111111111111\".\nIt will authenticate with the specified ClientSecret parameter: \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\".\n\n## PARAMETERS\n\n### -Name\nThe name of the json service that you are looking for\n\nDefault value is \"*\" to display all json services\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Url\nURL / URI for the D365FO environment you want to access\n\nIf you are working against a D365FO instance, it will be the URL / URI for the instance itself\n\nIf you are working against a D365 Talent / HR instance, this will have to be \"http://hr.talent.dynamics.com\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Tenant\nAzure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to access\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ClientId\nThe ClientId obtained from the Azure Portal when you created a Registered Application\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 4\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ClientSecret\nThe ClientSecret obtained from the Azure Portal when you created a Registered Application\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 5\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RawOutput\nInstructs the cmdlet to include the outer structure of the response received from the endpoint\n\nThe output will still be a PSCustomObject\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputAsJson\nInstructs the cmdlet to convert the output to a Json string\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### System.String\n## NOTES\nTags: DMF, OData, RestApi, Data Management Framework\n\nAuthor: Mötz Jensen (@Splaxi)\n\nIdea taken from http://www.ksaelen.be/wordpresses/dynamicsaxblog/2016/01/dynamics-ax-7-tip-what-services-are-exposed/\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365Label.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365Label\n\n## SYNOPSIS\nGet label from the label file from Dynamics 365 Finance & Operations environment\n\n## SYNTAX\n\n```\nGet-D365Label [[-BinDir] <String>] [-LabelFileId] <String> [[-Language] <String[]>] [[-Name] <String>]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet label from the label file from the running the Dynamics 365 Finance & Operations instance\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365Label -LabelFileId PRO\n```\n\nShows the entire list of labels that are available from the PRO label file.\nThe language is defaulted to \"en-US\".\n\n### EXAMPLE 2\n```\nGet-D365Label -LabelFileId PRO -Language da\n```\n\nShows the entire list of labels that are available from the PRO label file.\nShows only all \"da\" (Danish) labels.\n\n### EXAMPLE 3\n```\nGet-D365Label -LabelFileId PRO -Name \"@PRO59*\"\n```\n\nShows the labels available from the PRO label file where the name fits the search \"@PRO59*\"\n\nA result set example:\n\nName                 Value                                                                            Language\n----                 -----                                                                            --------\n@PRO59               Indicates if the type of the rebate value. \nen-US\n@PRO594              Pack consumption                                                                 en-US\n@PRO595              Pack qty now being released to production in the BOM unit. \nen-US\n@PRO596              Pack unit. \nen-US\n@PRO597              Pack proposal for release in the packing unit. \nen-US\n@PRO590              Constant pack qty                                                                en-US\n@PRO593              Pack proposal release in BOM unit. \nen-US\n@PRO598              Pack quantity now being released for the production in the packing unit. \nen-US\n\n### EXAMPLE 4\n```\nGet-D365Label -LabelFileId PRO -Name \"@PRO59*\" -Language da,en-us\n```\n\nShows the labels available from the PRO label file where the name fits the search \"@PRO59*\".\nShows for both \"da\" (Danish) and en-US (English)\n\n## PARAMETERS\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the AOS service PackagesLocalDirectory\\bin\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LabelFileId\nName / Id of the label \"file\" that you want to work against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Language\nName / string representation of the language / culture you want to work against\n\nDefault value is \"en-US\"\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: En-US\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Name\nName of the label that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"@PRO59*\"\n\nDefault value is \"*\" which will search for all labels\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: PackagesLocalDirectory, Servicing, Language, Labels, Label\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThis cmdlet is inspired by the work of \"Pedro Tornich\" (twitter: @ptornich)\n\nAll credits goes to him for showing how to extract these information\n\nHis github repository can be found here:\nhttps://github.com/ptornich/LabelFileGenerator\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365LabelFile.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365LabelFile\n\n## SYNOPSIS\nGet label file (ids) for packages / modules from Dynamics 365 Finance & Operations environment\n\n## SYNTAX\n\n```\nGet-D365LabelFile [[-BinDir] <String>] [[-PackageDirectory] <String>] [[-Module] <String>] [[-Name] <String>]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet label file (ids) for packages / modules from the machine running the AOS service for Dynamics 365 Finance & Operations\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365LabelFile\n```\n\nShows the entire list of label file (ids) for all installed packages / modules located in the default location on the machine\n\n### EXAMPLE 2\n```\nGet-D365LabelFile -Name \"Acc*Receivable*\"\n```\n\nShows the list of label file (ids) for all installed packages / modules where the label file (ids) name fits the search \"Acc*Receivable*\"\n\nA result set example:\n\nLabelFileId                        Languages              Module\n-----------                        ---------              ------\nAccountsReceivable                 {ar-AE, ar, cs, da...} ApplicationSuite\nAccountsReceivable_SalesTaxCodesSA {en-US}                ApplicationSuite\n\n### EXAMPLE 3\n```\nGet-D365LabelFile -PackageDirectory \"J:\\AOSService\\PackagesLocalDirectory\"\n```\n\nShows the list of label file (ids) for all installed packages / modules located in \"J:\\AOSService\\PackagesLocalDirectory\" on the machine\n\n## PARAMETERS\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the AOS service PackagesLocalDirectory\\bin\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Module\nName of the module that you want to work against\n\nDefault value is \"*\" which will search for all modules\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: ModuleName\n\nRequired: False\nPosition: 4\nDefault value: *\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Name\nName of the label file (id) that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"Acc*Receivable*\"\n\nDefault value is \"*\" which will search for all label file (ids)\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: PackagesLocalDirectory, Servicing, Language, Labels, Label\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThis cmdlet is inspired by the work of \"Pedro Tornich\" (twitter: @ptornich)\n\nAll credits goes to him for showing how to extract these information\n\nHis github repository can be found here:\nhttps://github.com/ptornich/LabelFileGenerator\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365Language.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365Language\n\n## SYNOPSIS\nGet installed languages from Dynamics 365 Finance & Operations environment\n\n## SYNTAX\n\n```\nGet-D365Language [[-BinDir] <String>] [[-Name] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet installed languages from the running the Dynamics 365 Finance & Operations instance\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365Language\n```\n\nShows the entire list of installed languages that are available from the running instance\n\n### EXAMPLE 2\n```\nGet-D365Language -Name \"fr*\"\n```\n\nShows the list of installed languages where the name fits the search \"fr*\"\n\nA result set example:\nfr      French\nfr-BE   French (Belgium)\nfr-CA   French (Canada)\nfr-CH   French (Switzerland)\n\n## PARAMETERS\n\n### -BinDir\nPath to the directory containing the BinDir and its assemblies\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Name\nName of the language that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"fr*\"\n\nDefault value is \"*\" which will search for all languages\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: PackagesLocalDirectory, Servicing, Language, Labels, Label\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThis cmdlet is inspired by the work of \"Pedro Tornich\" (twitter: @ptornich)\n\nAll credits goes to him for showing how to extract these information\n\nHis github repository can be found here:\nhttps://github.com/ptornich/LabelFileGenerator\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365LcsApiConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365LcsApiConfig\n\n## SYNOPSIS\nGet the LCS configuration details\n\n## SYNTAX\n\n```\nGet-D365LcsApiConfig [-OutputAsHashtable] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the LCS configuration details from the configuration store\n\nAll settings retrieved from this cmdlets is to be considered the default parameter values across the different cmdlets\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365LcsApiConfig\n```\n\nThis will output the current LCS API configuration.\nThe object returned will be a PSCustomObject.\n\n### EXAMPLE 2\n```\nGet-D365LcsApiConfig -OutputAsHashtable\n```\n\nThis will output the current LCS API configuration.\nThe object returned will be a Hashtable.\n\n## PARAMETERS\n\n### -OutputAsHashtable\nInstruct the cmdlet to return a hashtable object\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Environment, Url, Config, Configuration, LCS, Upload, ClientId\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Get-D365LcsApiToken]()\n\n[Get-D365LcsAssetValidationStatus]()\n\n[Get-D365LcsDeploymentStatus]()\n\n[Invoke-D365LcsApiRefreshToken]()\n\n[Invoke-D365LcsDeployment]()\n\n[Invoke-D365LcsUpload]()\n\n[Set-D365LcsApiConfig]()\n\n"
  },
  {
    "path": "docs/Get-D365LcsApiToken.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365LcsApiToken\n\n## SYNOPSIS\nGet a valid OAuth 2.0 access token for LCS\n\n## SYNTAX\n\n```\nGet-D365LcsApiToken [[-ClientId] <String>] [-Username] <String> [-Password] <String> [[-LcsApiUri] <String>]\n [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet a valid OAuth 2.0 access token for LCS, by providing an easy way to work against the Azure AD of your tenant\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365LcsApiToken -ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" -Username \"serviceaccount@domain.com\" -Password \"TopSecretPassword\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n```\n\nThis will obtain a valid OAuth 2.0 access token from Azure Active Directory.\nThe ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" is used in the OAuth 2.0 Grant Flow to authenticate.\nThe Username \"serviceaccount@domain.com\" and Password \"TopSecretPassword\" is used in the OAuth 2.0 Grant Flow, to approved that the application should impersonate like \"serviceaccount@domain.com\".\nThe http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n\n### EXAMPLE 2\n```\nGet-D365LcsApiToken -ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" -Username \"serviceaccount@domain.com\" -Password \"TopSecretPassword\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\" | Set-D365LcsApiConfig -ProjectId 123456789\n```\n\nThis will obtain a valid OAuth 2.0 access token from Azure Active Directory.\nThe ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" is used in the OAuth 2.0 Grant Flow to authenticate.\nThe Username \"serviceaccount@domain.com\" and Password \"TopSecretPassword\" is used in the OAuth 2.0 Grant Flow, to approved that the application should impersonate like \"serviceaccount@domain.com\".\nThe http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n\nThe output object received from Get-D365LcsApiToken is piped directly to Set-D365LcsApiConfig.\n\nSet-D365LcsApiConfig will save the ClientId, LcsApiUri, ProjectId, access_token(BearerToken), refresh_token(RefreshToken), expires_on(ActiveTokenExpiresOn) details for the module to use them across other LCS cmdlets.\n\nThis should be your default approach in using and leveraging the module, so you don't have to supply the same parameters for every single cmdlet.\n\n### EXAMPLE 3\n```\nGet-D365LcsApiToken -Username \"serviceaccount@domain.com\" -Password \"TopSecretPassword\"\n```\n\nThis will obtain a valid OAuth 2.0 access token from Azure Active Directory.\nThe Username \"serviceaccount@domain.com\" and Password \"TopSecretPassword\" is used in the OAuth 2.0 Grant Flow, to approved that the application should impersonate like \"serviceaccount@domain.com\".\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 4\n```\nGet-D365LcsApiToken -Username \"serviceaccount@domain.com\" -Password \"TopSecretPassword\" | Set-D365LcsApiConfig\n```\n\nThis will obtain a valid OAuth 2.0 access token from Azure Active Directory and save the needed details.\nThe Username \"serviceaccount@domain.com\" and Password \"TopSecretPassword\" is used in the OAuth 2.0 Grant Flow, to approved that the application should impersonate like \"serviceaccount@domain.com\".\nThe output object received from Get-D365LcsApiToken is piped directly to Set-D365LcsApiConfig.\nSet-D365LcsApiConfig will save the access_token(BearerToken), refresh_token(RefreshToken) and expires_on(ActiveTokenExpiresOn).\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n## PARAMETERS\n\n### -ClientId\nThe Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:LcsApiClientId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Username\nThe username of the account that you want to impersonate\n\nIt can either be your personal account or a service account\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Password\nThe password of the account that you want to impersonate\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Get-D365LcsApiConfig]()\n\n[Get-D365LcsAssetValidationStatus]()\n\n[Get-D365LcsDeploymentStatus]()\n\n[Invoke-D365LcsApiRefreshToken]()\n\n[Invoke-D365LcsDeployment]()\n\n[Invoke-D365LcsUpload]()\n\n[Set-D365LcsApiConfig]()\n\n"
  },
  {
    "path": "docs/Get-D365LcsAssetFile.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365LcsAssetFile\n\n## SYNOPSIS\nGet file from the Asset library inside the LCS project\n\n## SYNTAX\n\n```\nGet-D365LcsAssetFile [[-ProjectId] <Int32>] [[-FileType] <LcsAssetFileType>] [[-AssetName] <String>]\n [[-AssetVersion] <String>] [[-AssetFilename] <String>] [[-AssetDescription] <String>] [[-AssetId] <String>]\n [[-BearerToken] <String>] [[-LcsApiUri] <String>] [-Latest] [[-RetryTimeout] <TimeSpan>] [-EnableException]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the available files from the Asset Library in LCS project\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365LcsAssetFile -ProjectId 123456789 -FileType SoftwareDeployablePackage -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n```\n\nThis will list all Software Deployable Packages.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\nThe http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n\n### EXAMPLE 2\n```\nGet-D365LcsAssetFile -FileType SoftwareDeployablePackage\n```\n\nThis will list all Software Deployable Packages.\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 3\n```\nGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetFilename \"*MAIN*\"\n```\n\nThis will list all Software Deployable Packages, that matches the \"*MAIN*\" search pattern in the AssetFilename.\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\nIt will filter the output to match the AssetFilename \"*MAIN*\" search pattern.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 4\n```\nGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetName \"*MAIN*\"\n```\n\nThis will list all Software Deployable Packages, that matches the \"*MAIN*\" search pattern in the AssetName.\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\nIt will filter the output to match the AssetName \"*MAIN*\" search pattern.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 5\n```\nGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetDescription \"*TEST*\"\n```\n\nThis will list all Software Deployable Packages, that matches the \"*TEST*\" search pattern in the AssetDescription.\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\nIt will filter the output to match the AssetDescription \"*TEST*\" search pattern.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 6\n```\nGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetId \"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\"\n```\n\nThis will list all Software Deployable Packages, that matches the \"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\" search pattern in the AssetId.\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\nIt will filter the output to match the AssetId \"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\" search pattern.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 7\n```\nGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -Latest | Invoke-D365AzCopyTransfer -DestinationUri C:\\Temp\\d365fo.tools -FileName \"Main.zip\" -ShowOriginalProgress\n```\n\nThis will download the latest Software Deployable Package from the Asset Library in LCS onto your on machine.\nIt will list Software Deployable Packages based on the FileType parameter.\nIt will list the latest (newest) Software Deployable Package.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 8\n```\nGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -RetryTimeout \"00:01:00\"\n```\n\nThis will list all Software Deployable Packages, and allow for the cmdlet to retry for no more than 1 minute.\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n## PARAMETERS\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:LcsApiProjectId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FileType\nType of file you want to list from the LCS Asset Library\n\nValid options:\n\"Model\"\n\"Process Data Package\"\n\"Software Deployable Package\"\n\"GER Configuration\"\n\"Data Package\"\n\"PowerBI Report Model\"\n\"E-Commerce Package\"\n\"NuGet Package\"\n\"Retail Self-Service Package\"\n\"Commerce Cloud Scale Unit Extension\"\n\n\nDefault value is \"Software Deployable Package\"\n\n```yaml\nType: LcsAssetFileType\nParameter Sets: (All)\nAliases:\nAccepted values: Model, ProcessDataPackage, SoftwareDeployablePackage, GERConfiguration, DataPackage, PowerBIReportModel, ECommercePackage, NuGetPackage, RetailSelfServicePackage, CommerceCloudScaleUnitExtension\n\nRequired: False\nPosition: 2\nDefault value: SoftwareDeployablePackage\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AssetName\nName of the asset that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-AssetName \"*ISV*\"\n\nDefault value is \"*\" which will search for all assets via the Name property\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AssetVersion\nVersion of the Asset file that you are looking for\n\nIt does a simple compare against the response from LCS and only lists the ones that matches\n\nAccepts wildcards for searching.\nE.g.\n-AssetVersion \"*ISV*\"\n\nDefault value is \"*\" which will search for all files\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AssetFilename\nName of the file that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-AssetFilename \"*ISV*\"\n\nDefault value is \"*\" which will search for all files via the FileName property\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AssetDescription\nName of the file that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-AssetDescription \"*ISV*\"\n\nDefault value is \"*\" which will search for all files via the FileDescription property\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AssetId\nId of the file that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-AssetId \"*ISV*\"\n\nDefault value is \"*\" which will search for all files via the AssetId property\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Token\n\nRequired: False\nPosition: 8\nDefault value: $Script:LcsApiBearerToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 9\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Latest\nInstruct the cmdlet to only fetch the latest file from the Asset Library from LCS\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases: GetLatest\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RetryTimeout\nThe retry timeout, before the cmdlet should quit retrying based on the 429 status code\n\nNeeds to be provided in the timspan notation:\n\"hh:mm:ss\"\n\nhh is the number of hours, numerical notation only\nmm is the number of minutes\nss is the numbers of seconds\n\nEach section of the timeout has to valid, e.g.\nhh can maximum be 23\nmm can maximum be 59\nss can maximum be 59\n\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n\n```yaml\nType: TimeSpan\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 10\nDefault value: 00:00:00\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Get-D365LcsApiConfig]()\n\n[Get-D365LcsApiToken]()\n\n[Invoke-D365LcsApiRefreshToken]()\n\n[Set-D365LcsApiConfig]()\n\n[Get-D365LcsSharedAssetFile]()\n\n"
  },
  {
    "path": "docs/Get-D365LcsAssetValidationStatus.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365LcsAssetValidationStatus\n\n## SYNOPSIS\nGet the validation status from LCS\n\n## SYNTAX\n\n```\nGet-D365LcsAssetValidationStatus [-AssetId] <String> [[-ProjectId] <Int32>] [[-BearerToken] <String>]\n [[-LcsApiUri] <String>] [-WaitForValidation] [[-SleepInSeconds] <Int32>] [[-RetryTimeout] <TimeSpan>]\n [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the validation status for a given file in the Asset Library in LCS\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365LcsAssetValidationStatus -ProjectId 123456789 -BearerToken \"JldjfafLJdfjlfsalfd...\" -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n```\n\nThis will check the validation status for the file in the Asset Library.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\nThe request will authenticate with the BearerToken \"Bearer JldjfafLJdfjlfsalfd...\".\nThe http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n\n### EXAMPLE 2\n```\nGet-D365LcsAssetValidationStatus -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\"\n```\n\nThis will check the validation status for the file in the Asset Library.\nThe file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 3\n```\nGet-D365LcsAssetValidationStatus -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -WaitForValidation\n```\n\nThis will check the validation status for the file in the Asset Library.\nThe file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\nThe cmdlet will every 60 seconds contact the LCS API endpoint and check if the status of the validation is either success or failure.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 4\n```\nInvoke-D365LcsUpload -FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\" | Get-D365LcsAssetValidationStatus -WaitForValidation\n```\n\nThis will start the upload of a file to the Asset Library and check the validation status for the file in the Asset Library.\nThe file that will be uploaded is based on the FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\".\nThe output object received from Invoke-D365LcsUpload is piped directly to Get-D365LcsAssetValidationStatus.\nThe cmdlet will every 60 seconds contact the LCS API endpoint and check if the status of the validation is either success or failure.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 5\n```\nGet-D365LcsAssetValidationStatus -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -RetryTimeout \"00:01:00\"\n```\n\nThis will check the validation status for the file in the Asset Library, and allow for the cmdlet to retry for no more than 1 minute.\nThe file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n## PARAMETERS\n\n### -AssetId\nThe unique id of the asset / file that you are trying to deploy from LCS\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:LcsApiProjectId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Token\n\nRequired: False\nPosition: 3\nDefault value: $Script:LcsApiBearerToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -WaitForValidation\nInstruct the cmdlet to wait for the validation process to complete\n\nThe cmdlet will sleep for 60 seconds, before requesting the status of the validation process from LCS\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SleepInSeconds\nTime in seconds that you want the cmdlet to use as the sleep timer between each request against the LCS endpoint\n\nDefault value is 60\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: 60\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RetryTimeout\nThe retry timeout, before the cmdlet should quit retrying based on the 429 status code\n\nNeeds to be provided in the timspan notation:\n\"hh:mm:ss\"\n\nhh is the number of hours, numerical notation only\nmm is the number of minutes\nss is the numbers of seconds\n\nEach section of the timeout has to valid, e.g.\nhh can maximum be 23\nmm can maximum be 59\nss can maximum be 59\n\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n\n```yaml\nType: TimeSpan\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: 00:00:00\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Get-D365LcsApiConfig]()\n\n[Get-D365LcsApiToken]()\n\n[Get-D365LcsDeploymentStatus]()\n\n[Invoke-D365LcsApiRefreshToken]()\n\n[Invoke-D365LcsDeployment]()\n\n[Invoke-D365LcsUpload]()\n\n[Set-D365LcsApiConfig]()\n\n"
  },
  {
    "path": "docs/Get-D365LcsDatabaseBackups.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365LcsDatabaseBackups\n\n## SYNOPSIS\nGet database backups from LCS project\n\n## SYNTAX\n\n```\nGet-D365LcsDatabaseBackups [[-ProjectId] <Int32>] [[-BearerToken] <String>] [[-LcsApiUri] <String>] [-Latest]\n [[-RetryTimeout] <TimeSpan>] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the available database backups from the Asset Library in LCS project\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365LcsDatabaseBackups -ProjectId 123456789 -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n```\n\nThis will get all available database backups from the Asset Library inside LCS.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe request will authenticate with the BearerToken \"Bearer JldjfafLJdfjlfsalfd...\".\nThe http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n\n### EXAMPLE 2\n```\nGet-D365LcsDatabaseBackups\n```\n\nThis will get all available database backups from the Asset Library inside LCS.\nIt will use default values for all parameters.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 3\n```\nGet-D365LcsDatabaseBackups -Latest\n```\n\nThis will get the latest available database backup from the Asset Library inside LCS.\nIt will use default values for all parameters.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 4\n```\nGet-D365LcsDatabaseBackups -Latest -RetryTimeout \"00:01:00\"\n```\n\nThis will get the latest available database backup from the Asset Library inside LCS, and allow for the cmdlet to retry for no more than 1 minute.\nIt will use default values for all parameters.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n## PARAMETERS\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:LcsApiProjectId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Token\n\nRequired: False\nPosition: 2\nDefault value: $Script:LcsApiBearerToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Latest\nInstruct the cmdlet to only fetch the latest file from the Azure Storage Account\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases: GetLatest\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RetryTimeout\nThe retry timeout, before the cmdlet should quit retrying based on the 429 status code\n\nNeeds to be provided in the timspan notation:\n\"hh:mm:ss\"\n\nhh is the number of hours, numerical notation only\nmm is the number of minutes\nss is the numbers of seconds\n\nEach section of the timeout has to valid, e.g.\nhh can maximum be 23\nmm can maximum be 59\nss can maximum be 59\n\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n\n```yaml\nType: TimeSpan\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: 00:00:00\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Get-D365LcsApiConfig]()\n\n[Get-D365LcsApiToken]()\n\n[Invoke-D365LcsApiRefreshToken]()\n\n[Set-D365LcsApiConfig]()\n\n"
  },
  {
    "path": "docs/Get-D365LcsDatabaseOperationStatus.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365LcsDatabaseOperationStatus\n\n## SYNOPSIS\nGet the status of a database operation from LCS\n\n## SYNTAX\n\n```\nGet-D365LcsDatabaseOperationStatus [[-ProjectId] <Int32>] [[-BearerToken] <String>]\n [-OperationActivityId] <String> [-EnvironmentId] <String> [[-LcsApiUri] <String>] [-WaitForCompletion]\n [[-SleepInSeconds] <Int32>] [[-RetryTimeout] <TimeSpan>] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the current status of a database operation against an environment from a LCS project\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365LcsDatabaseOperationStatus -ProjectId 123456789 -OperationActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n```\n\nThis will check the database operation status of a specific OperationActivityId against an environment.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\nThe request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\nThe http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n\n### EXAMPLE 2\n```\nGet-D365LcsDatabaseOperationStatus -OperationActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n```\n\nThis will check the database operation status of a specific OperationActivityId against an environment.\nThe OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 3\n```\nGet-D365LcsDatabaseOperationStatus -OperationActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -WaitForCompletion\n```\n\nThis will check the database operation status of a specific OperationActivityId against an environment.\nThe OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\nThe cmdlet will every 300 seconds contact the LCS API endpoint and check if the status of the database operation status is either success or failure.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 4\n```\nGet-D365LcsDatabaseOperationStatus -OperationActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -RetryTimeout \"00:01:00\"\n```\n\nThis will check the database operation status of a specific OperationActivityId against an environment, and allow for the cmdlet to retry for no more than 1 minute.\nThe OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n## PARAMETERS\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:LcsApiProjectId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Token\n\nRequired: False\nPosition: 2\nDefault value: $Script:LcsApiBearerToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OperationActivityId\nThe unique id of the operaction activity that identitfies the database operation\n\nIt will be part of the output from the different Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: ActivityId\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -EnvironmentId\nThe unique id of the environment that you want to work against\n\nThe Id can be located inside the LCS portal\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: SourceEnvironmentId\n\nRequired: True\nPosition: 4\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -WaitForCompletion\nInstruct the cmdlet to wait for the deployment process to complete\n\nThe cmdlet will sleep for 300 seconds, before requesting the status of the deployment process from LCS\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SleepInSeconds\nTime in seconds that you want the cmdlet to use as the sleep timer between each request against the LCS endpoint\n\nDefault value is 300\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: 300\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RetryTimeout\nThe retry timeout, before the cmdlet should quit retrying based on the 429 status code\n\nNeeds to be provided in the timspan notation:\n\"hh:mm:ss\"\n\nhh is the number of hours, numerical notation only\nmm is the number of minutes\nss is the numbers of seconds\n\nEach section of the timeout has to valid, e.g.\nhh can maximum be 23\nmm can maximum be 59\nss can maximum be 59\n\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n\n```yaml\nType: TimeSpan\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: 00:00:00\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### PSCustomObject\n## NOTES\nTags: Environment, Config, Configuration, LCS, Database backup, Api, Backup, Restore, Refresh\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Get-D365LcsApiConfig]()\n\n[Get-D365LcsApiToken]()\n\n[Get-D365LcsAssetValidationStatus]()\n\n[Invoke-D365LcsApiRefreshToken]()\n\n[Invoke-D365LcsDeployment]()\n\n[Invoke-D365LcsUpload]()\n\n[Set-D365LcsApiConfig]()\n\n"
  },
  {
    "path": "docs/Get-D365LcsDeploymentStatus.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365LcsDeploymentStatus\n\n## SYNOPSIS\nGet the Deployment status from LCS\n\n## SYNTAX\n\n```\nGet-D365LcsDeploymentStatus [[-ProjectId] <Int32>] [[-BearerToken] <String>] [-ActivityId] <String>\n [-EnvironmentId] <String> [[-LcsApiUri] <String>] [-WaitForCompletion] [[-SleepInSeconds] <Int32>]\n [-FailOnErrorMessage] [[-RetryTimeout] <TimeSpan>] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the Deployment status for activity against an environment from the Dynamics LCS Portal\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365LcsDeploymentStatus -ProjectId 123456789 -ActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -BearerToken \"Bearer JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n```\n\nThis will check the deployment status of specific activity against an environment.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\nThe request will authenticate with the BearerToken \"Bearer JldjfafLJdfjlfsalfd...\".\nThe http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n\n### EXAMPLE 2\n```\nGet-D365LcsDeploymentStatus -ActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n```\n\nThis will check the deployment status of specific activity against an environment.\nThe activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 3\n```\nGet-D365LcsDeploymentStatus -ActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -WaitForCompletion\n```\n\nThis will check the deployment status of specific activity against an environment.\nThe activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\nThe cmdlet will every 300 seconds contact the LCS API endpoint and check if the status of the deployment is either success or failure.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 4\n```\nGet-D365LcsDeploymentStatus -ActivityId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -RetryTimeout \"00:01:00\"\n```\n\nThis will check the deployment status of specific activity against an environment, and allow for the cmdlet to retry for no more than 1 minute.\nThe activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n## PARAMETERS\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:LcsApiProjectId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Token\n\nRequired: False\nPosition: 2\nDefault value: $Script:LcsApiBearerToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ActivityId\nThe unique id of the action that you started from the Invoke-D365LcsDeployment cmdlet\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: ActionHistoryId\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -EnvironmentId\nThe unique id of the environment that you want to work against\n\nThe Id can be located inside the LCS portal\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 4\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -WaitForCompletion\nInstruct the cmdlet to wait for the deployment process to complete\n\nThe cmdlet will sleep for 300 seconds, before requesting the status of the deployment process from LCS\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SleepInSeconds\nTime in secounds that you want the cmdlet to use as the sleep timer between each request against the LCS endpoint\n\nDefault value is 300\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: 300\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FailOnErrorMessage\nInstruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\nThis allows you to implement custom retry / error handling logic\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RetryTimeout\nThe retry timeout, before the cmdlet should quit retrying based on the 429 status code\n\nNeeds to be provided in the timspan notation:\n\"hh:mm:ss\"\n\nhh is the number of hours, numerical notation only\nmm is the number of minutes\nss is the numbers of seconds\n\nEach section of the timeout has to valid, e.g.\nhh can maximum be 23\nmm can maximum be 59\nss can maximum be 59\n\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n\n```yaml\nType: TimeSpan\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: 00:00:00\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### PSCustomObject\n## NOTES\nTags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token, Deployment, Deploy\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Get-D365LcsApiConfig]()\n\n[Get-D365LcsApiToken]()\n\n[Get-D365LcsAssetValidationStatus]()\n\n[Invoke-D365LcsApiRefreshToken]()\n\n[Invoke-D365LcsDeployment]()\n\n[Invoke-D365LcsUpload]()\n\n[Set-D365LcsApiConfig]()\n\n"
  },
  {
    "path": "docs/Get-D365LcsEnvironmentHistory.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365LcsEnvironmentHistory\n\n## SYNOPSIS\nGet history for a given environment within a LCS project\n\n## SYNTAX\n\n### Default (Default)\n```\nGet-D365LcsEnvironmentHistory [-ProjectId <Int32>] [-BearerToken <String>] -EnvironmentId <String>\n [-LcsApiUri <String>] [-FailOnErrorMessage] [-RetryTimeout <TimeSpan>] [-EnableException] [<CommonParameters>]\n```\n\n### Pagination\n```\nGet-D365LcsEnvironmentHistory [-ProjectId <Int32>] [-BearerToken <String>] -EnvironmentId <String>\n [-TraverseAllPages] [-FirstPages <Int32>] [-LcsApiUri <String>] [-FailOnErrorMessage]\n [-RetryTimeout <TimeSpan>] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet history details for a given environment from within a LCS project\n\nThere can be multiple pages of data, which requires you to use the TraverseAllPages parameter, if you want all data to be shown\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365LcsEnvironmentHistory -ProjectId \"123456789\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n```\n\nThis will list the first page of Environment History Data from the LCS API.\nThe LCS project is identified by the ProjectId \"123456789\", which can be obtained in the LCS portal.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n\nA result set example:\n\nName             : Service Update - 10.0.19\nType             : SFBinaryHotfix\nTypeDisplay      : Binary hotfix\nStartDateTimeUTC : 2021-07-11T00:01:57.423\nEndDateTimeUTC   : 2021-07-11T05:01:12.97\nStatus           : Completed\nActivityId       : e3509860-61d4-4003-9b45-6ea7d89aea30\nEnvironmentId    : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\nProjectId        : 123456789\n\nName             : Refresh database\nType             : SFSourceDbToSandbox\nTypeDisplay      : Refresh database\nStartDateTimeUTC : 2021-06-06T15:17:48.87\nEndDateTimeUTC   : 2021-06-06T16:33:40.367\nStatus           : Completed\nActivityId       : e3509860-61d4-4003-9b45-6ea7d89aea31\nEnvironmentId    : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\nProjectId        : 123456789\n\nName             : Export database\nType             : SFExportSandboxDb\nTypeDisplay      : Export database\nStartDateTimeUTC : 2021-04-27T22:08:01.103\nEndDateTimeUTC   : 2021-04-28T23:30:06.623\nStatus           : RollbackCompleted\nActivityId       : e3509860-61d4-4003-9b45-6ea7d89aea32\nEnvironmentId    : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\nProjectId        : 123456789\n\nName             : Main_2021.1.1.1\nType             : SFApplicationHotfix\nTypeDisplay      : Application deployable package\nStartDateTimeUTC : 2021-03-04T21:44:20.793\nEndDateTimeUTC   : 2021-03-04T22:48:17.303\nStatus           : Completed\nActivityId       : e3509860-61d4-4003-9b45-6ea7d89aea33\nEnvironmentId    : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\nProjectId        : 123456789\n\n### EXAMPLE 2\n```\nGet-D365LcsEnvironmentHistory -ProjectId \"123456789\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -TraverseAllPages\n```\n\nThis will list the all the pages of Environment History Data from the LCS API.\nThe LCS project is identified by the ProjectId \"123456789\", which can be obtained in the LCS portal.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\nThe cmdlet will TraverseAllPages from the LCS API.\nIt will use the default value for the maximum number of pages to return, 99 pages.\n\nTraverseAllPages will increase the request time for completion, based on how many entries there is in the history.\nPlease be patient and let the system work for you.\n\nPlease note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\n\n### EXAMPLE 3\n```\nGet-D365LcsEnvironmentHistory -ProjectId \"123456789\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -TraverseAllPages -FirstPages 2\n```\n\nThis will list the all the pages of Environment History Data from the LCS API.\nThe LCS project is identified by the ProjectId \"123456789\", which can be obtained in the LCS portal.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\nThe cmdlet will TraverseAllPages from the LCS API.\nThe cmdlet will be fetching the FirstPages 2, to limit the output from the cmdlet to only the newest 2 pages.\n\nTraverseAllPages will increase the request time for completion, based on how many entries there is in the history.\nPlease be patient and let the system work for you.\n\nPlease note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\n\n## PARAMETERS\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:LcsApiProjectId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Token\n\nRequired: False\nPosition: Named\nDefault value: $Script:LcsApiBearerToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnvironmentId\nId of the environment that you want to be working against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -TraverseAllPages\nInstruct the cmdlet to fetch all pages, until there isn't more data available\n\nThis can be a slow operation, as it has to call the LCS API multiple times, fetching a single page per call\n\n```yaml\nType: SwitchParameter\nParameter Sets: Pagination\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FirstPages\nInstruct the cmdlet how many pages that you want it to retrieve from the LCS API\n\nCan only be used in combination with -TraverseAllPages\n\nThe default value is: 99 pages, which should be more than enough\n\nPlease note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\n\n```yaml\nType: Int32\nParameter Sets: Pagination\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: 99\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FailOnErrorMessage\nInstruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\nThis allows you to implement custom retry / error handling logic\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RetryTimeout\nThe retry timeout, before the cmdlet should quit retrying based on the 429 status code\n\nNeeds to be provided in the timspan notation:\n\"hh:mm:ss\"\n\nhh is the number of hours, numerical notation only\nmm is the number of minutes\nss is the numbers of seconds\n\nEach section of the timeout has to valid, e.g.\nhh can maximum be 23\nmm can maximum be 59\nss can maximum be 59\n\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n\n```yaml\nType: TimeSpan\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: 00:00:00\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### PSCustomObject\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365LcsEnvironmentMetadata.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365LcsEnvironmentMetadata\n\n## SYNOPSIS\nGet LCS environment meta data from within a project\n\n## SYNTAX\n\n### Default (Default)\n```\nGet-D365LcsEnvironmentMetadata [-ProjectId <Int32>] [-BearerToken <String>] [-LcsApiUri <String>]\n [-FailOnErrorMessage] [-RetryTimeout <TimeSpan>] [-EnableException] [<CommonParameters>]\n```\n\n### SearchByEnvironmentId\n```\nGet-D365LcsEnvironmentMetadata [-ProjectId <Int32>] [-BearerToken <String>] [-EnvironmentId <String>]\n [-LcsApiUri <String>] [-FailOnErrorMessage] [-RetryTimeout <TimeSpan>] [-EnableException] [<CommonParameters>]\n```\n\n### SearchByEnvironmentName\n```\nGet-D365LcsEnvironmentMetadata [-ProjectId <Int32>] [-BearerToken <String>] [-EnvironmentName <String>]\n [-LcsApiUri <String>] [-FailOnErrorMessage] [-RetryTimeout <TimeSpan>] [-EnableException] [<CommonParameters>]\n```\n\n### Pagination\n```\nGet-D365LcsEnvironmentMetadata [-ProjectId <Int32>] [-BearerToken <String>] [-TraverseAllPages]\n [-FirstPages <Int32>] [-LcsApiUri <String>] [-FailOnErrorMessage] [-RetryTimeout <TimeSpan>]\n [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet all meta data details for environments from within a LCS project\n\nIt supports listing all environments, but also supports single / specific environments by searching based on EnvironmentId or EnvironmentName\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365LcsEnvironmentMetadata -ProjectId \"123456789\"\n```\n\nThis will show metadata for every available environment from the LCS project.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\n\nThe request time for completion is directly impacted by the number of environments within the LCS project.\nPlease be patient and let the system work for you.\n\nYou might experience that not all environments are listed with this request, that would indicate that the LCS project has many environments.\nPlease use the -TraverseAllPages parameter to ensure that all environments are outputted.\n\nA result set example (Tier1):\n\nEnvironmentId                  : c6566087-23bd-4561-8247-4d7f4efd3172\nEnvironmentName                : DevBox-01\nProjectId                      : 123456789\nEnvironmentInfrastructure      : CustomerManaged\nEnvironmentType                : DevTestDev\nEnvironmentGroup               : Primary\nEnvironmentProduct             : Finance and Operations\nEnvironmentEndpointBaseUrl     : https://devbox-4d7f4efd3172devaos.cloudax.dynamics.com/\nDeploymentState                : Stopped\nTopologyDisplayName            : Finance and Operations - Develop (10.0.18 with Platform update 42)\nCurrentApplicationBuildVersion : 10.0.793.41\nCurrentApplicationReleaseName  : 10.0.18\nCurrentPlatformReleaseName     : Update42\nCurrentPlatformVersion         : 7.0.5968.16999\nDeployedOnUTC                  : 7/5/2021 11:19 AM\nCloudStorageLocation           : West Europe\nDisasterRecoveryLocation       : North Europe\nDeploymentStatusDisplay        : Stopped\nCanStart                       : True\nCanStop                        : False\n\nA result set example (Tier2+):\n\nEnvironmentId                  : e7c53b85-8b6a-4ab9-8985-1e1ea89a0f0a\nEnvironmentName                : Contoso-SIT\nProjectId                      : 123456789\nEnvironmentInfrastructure      : SelfService\nEnvironmentType                : Sandbox\nEnvironmentGroup               : Primary\nEnvironmentProduct             : Finance and Operations\nEnvironmentEndpointBaseUrl     : https://Contoso-SIT.sandbox.operations.dynamics.com/\nDeploymentState                : Finished\nTopologyDisplayName            : AXHA\nCurrentApplicationBuildVersion : 10.0.761.10019\nCurrentApplicationReleaseName  : 10.0.17\nCurrentPlatformReleaseName     : PU41\nCurrentPlatformVersion         : 7.0.5934.35741\nDeployedOnUTC                  : 4/1/2020 9:35 PM\nCloudStorageLocation           : West Europe\nDisasterRecoveryLocation       :\nDeploymentStatusDisplay        : Deployed\nCanStart                       : False\nCanStop                        : False\n\nA result set example (PROD):\n\nEnvironmentId                  : a8aab4f4-d4f3-41f0-af80-54cea83b50d2\nEnvironmentName                : Contoso-PROD\nProjectId                      : 123456789\nEnvironmentInfrastructure      : SelfService\nEnvironmentType                : Production\nEnvironmentGroup               : Primary\nEnvironmentProduct             : Finance and Operations\nEnvironmentEndpointBaseUrl     : https://Contoso-PROD.operations.dynamics.com/\nDeploymentState                : Finished\nTopologyDisplayName            : AXHA\nCurrentApplicationBuildVersion : 10.0.886.48\nCurrentApplicationReleaseName  : 10.0.20\nCurrentPlatformReleaseName     : PU44\nCurrentPlatformVersion         : 7.0.6060.45\nDeployedOnUTC                  : 4/9/2020 12:11 PM\nCloudStorageLocation           : West Europe\nDisasterRecoveryLocation       :\nDeploymentStatusDisplay        : Deployed\nCanStart                       : False\nCanStop                        : False\n\n### EXAMPLE 2\n```\nGet-D365LcsEnvironmentMetadata -ProjectId \"123456789\" -TraverseAllPages\n```\n\nThis will show metadata for every available environment from the LCS project, across multiple pages.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nIt will use the default value for the maximum number of pages to return, 99 pages.\n\nTraverseAllPages will increase the request time for completion, based on how many entries there is in the history.\nPlease be patient and let the system work for you.\n\nPlease note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\n\n### EXAMPLE 3\n```\nGet-D365LcsEnvironmentMetadata -ProjectId \"123456789\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n```\n\nThis will show metadata for every available environment from the LCS project.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n\n### EXAMPLE 4\n```\nGet-D365LcsEnvironmentMetadata -ProjectId \"123456789\" -EnvironmentName \"Contoso-SIT\"\n```\n\nThis will show metadata for every available environment from the LCS project.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe environment is identified by the EnvironmentName \"Contoso-SIT\", which can be obtained in the LCS portal.\n\n### EXAMPLE 5\n```\nGet-D365LcsEnvironmentMetadata -ProjectId \"123456789\" -TraverseAllPages -FirstPages 2\n```\n\nThis will show metadata for every available environment from the LCS project, across multiple pages.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nIt will use the default value for the maximum number of pages to return, 99 pages.\nThe cmdlet will be fetching the FirstPages 2, to limit the output from the cmdlet to only the newest 2 pages.\n\nTraverseAllPages will increase the request time for completion, based on how many entries there is in the history.\nPlease be patient and let the system work for you.\n\nPlease note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\n\n## PARAMETERS\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:LcsApiProjectId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Token\n\nRequired: False\nPosition: Named\nDefault value: $Script:LcsApiBearerToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnvironmentId\nId of the environment that you want to be working against\n\n```yaml\nType: String\nParameter Sets: SearchByEnvironmentId\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnvironmentName\nName of the environment that you want to be working against\n\n```yaml\nType: String\nParameter Sets: SearchByEnvironmentName\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -TraverseAllPages\nInstruct the cmdlet to fetch all pages, until there isn't more data available\n\nThis can be a slow operation, as it has to call the LCS API multiple times, fetching a single page per call\n\n```yaml\nType: SwitchParameter\nParameter Sets: Pagination\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FirstPages\nInstruct the cmdlet how many pages that you want it to retrieve from the LCS API\n\nCan only be used in combination with -TraverseAllPages\n\nThe default value is: 99 pages, which should be more than enough\n\nPlease note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint\n\n```yaml\nType: Int32\nParameter Sets: Pagination\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: 99\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FailOnErrorMessage\nInstruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\nThis allows you to implement custom retry / error handling logic\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RetryTimeout\nThe retry timeout, before the cmdlet should quit retrying based on the 429 status code\n\nNeeds to be provided in the timspan notation:\n\"hh:mm:ss\"\n\nhh is the number of hours, numerical notation only\nmm is the number of minutes\nss is the numbers of seconds\n\nEach section of the timeout has to valid, e.g.\nhh can maximum be 23\nmm can maximum be 59\nss can maximum be 59\n\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n\n```yaml\nType: TimeSpan\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: 00:00:00\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### PSCustomObject\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365LcsEnvironmentRsatCertificate.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365LcsEnvironmentRsatCertificate\n\n## SYNOPSIS\nGet LCS environment rsat certificate from within a project\n\n## SYNTAX\n\n```\nGet-D365LcsEnvironmentRsatCertificate [[-ProjectId] <Int32>] [[-BearerToken] <String>]\n [-EnvironmentId] <String> [[-OutputPath] <String>] [[-LcsApiUri] <String>] [-FailOnErrorMessage]\n [[-RetryTimeout] <TimeSpan>] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nDownload and persist the active rsat certificate from environments from within a LCS project\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365LcsEnvironmentRsatCertificate -ProjectId \"123456789\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n```\n\nThis will download the active rsat certificate file for the environment from the LCS project.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n\nA result set example:\n\nPath     : c:\\temp\\d365fo.tools\\RsatCert\\RSATCertificate_ABC-UAT_20240101-012030\nCerFile  : C:\\temp\\d365fo.tools\\RsatCert\\RSATCertificate_ABC-UAT_20240101-012030\\RSATCertificate_ABC-UAT_20240101-012030.cer\nPfxFile  : C:\\temp\\d365fo.tools\\RsatCert\\RSATCertificate_ABC-UAT_20240101-012030\\RSATCertificate_ABC-UAT_20240101-012030.pfx\nFileName : RSATCertificate_ABC-UAT_20240101-012030.zip\nPassword : 9zbPiLMTk676mkq5FvqQ\n\n### EXAMPLE 2\n```\nGet-D365LcsEnvironmentRsatCertificate -ProjectId \"123456789\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" | Import-D365RsatSelfServiceCertificates\n```\n\nThis will download the active rsat certificate file for the environment from the LCS project.\nThe resulting files are then imported into the certificate store on the local machine.\n\n## PARAMETERS\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:LcsApiProjectId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Token\n\nRequired: False\nPosition: 2\nDefault value: $Script:LcsApiBearerToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnvironmentId\nId of the environment that you want to be working against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputPath\nPath to where you want the certificate files to be saved\n\nThe default value is: \"c:\\temp\\d365fo.tools\\RsatCert\\\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $(Join-Path $Script:DefaultTempPath \"RsatCert\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FailOnErrorMessage\nInstruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\nThis allows you to implement custom retry / error handling logic\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RetryTimeout\nThe retry timeout, before the cmdlet should quit retrying based on the 429 status code\n\nNeeds to be provided in the timspan notation:\n\"hh:mm:ss\"\n\nhh is the number of hours, numerical notation only\nmm is the number of minutes\nss is the numbers of seconds\n\nEach section of the timeout has to valid, e.g.\nhh can maximum be 23\nmm can maximum be 59\nss can maximum be 59\n\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n\n```yaml\nType: TimeSpan\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: 00:00:00\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### PSCustomObject\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365LcsSharedAssetFile.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365LcsSharedAssetFile\n\n## SYNOPSIS\nGet information for assets from the shared asset library of LCS\n\n## SYNTAX\n\n```\nGet-D365LcsSharedAssetFile [[-ProjectId] <Int32>] [[-FileType] <LcsAssetFileType>] [[-AssetName] <String>]\n [[-AssetVersion] <String>] [[-AssetFilename] <String>] [[-AssetDescription] <String>] [[-AssetId] <String>]\n [[-BearerToken] <String>] [[-LcsApiUri] <String>] [-Latest] [-SkipSasGeneration] [[-RetryTimeout] <TimeSpan>]\n [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the information for the file assets from the shared asset library of LCS matching the search criteria\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365LcsSharedAssetFile -ProjectId 123456789 -FileType SoftwareDeployablePackage -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n```\n\nThis will list all Software Deployable Packages in the shared asset library.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\nThe http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n\n### EXAMPLE 2\n```\nGet-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage\n```\n\nThis will list all Software Deployable Packages in the shared asset library.\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 3\n```\nGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetFilename \"*MAIN*\"\n```\n\nThis will list all Software Deployable Packages in the shared asset library that match the \"*MAIN*\" search pattern in the file name of the asset.\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\nIt will filter the output to match the AssetFilename \"*MAIN*\" search pattern.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 4\n```\nGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetName \"*MAIN*\"\n```\n\nThis will list all Software Deployable Packages in the shared asset library that match the \"*MAIN*\" search pattern in the name of the asset.\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\nIt will filter the output to match the AssetName \"*MAIN*\" search pattern.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 5\n```\nGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetDescription \"*TEST*\"\n```\n\nThis will list all Software Deployable Packages in the shared asset library that match the \"*TEST*\" search pattern in the asset description.\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\nIt will filter the output to match the AssetDescription \"*TEST*\" search pattern.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 6\n```\nGet-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetId \"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\"\n```\n\nThis will list all Software Deployable Packages in the shared asset library that match the \"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\" search pattern in the asset id.\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\nIt will filter the output to match the AssetId \"500dd860-eacf-4e04-9f18-f9c8fe1d8e03\" search pattern.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 7\n```\n$asset = Get-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage -Latest\n```\n\nPS C:\\\\\\> Invoke-D365AzCopyTransfer -SourceUri $asset.FileLocation -DestinationUri C:\\Temp\\d365fo.tools\\$($asset.Filename) -ShowOriginalProgress\n\nThis will download the latest Software Deployable Package from the shared asset library in LCS onto your local machine.\nIt will list Software Deployable Packages based on the FileType parameter.\nIt will list the latest (newest) Software Deployable Package.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 8\n```\nGet-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage -RetryTimeout \"00:01:00\"\n```\n\nThis will list all Software Deployable Packages in the shared asset library and allow for the cmdlet to retry for no more than 1 minute.\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 9\n```\nGet-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage -SkipSasGeneration\n```\n\nThis will list all Software Deployable Packages in the shared asset library, but skip the SAS / Download generation\nIt will search for SoftwareDeployablePackage by using the FileType parameter.\n\nThis will increase the speed getting the list of assets - but you will not get a downloadable link.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n## PARAMETERS\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\n\nDefault value can be configured using Set-D365LcsApiConfig\n\nAlthough the assets are stored in the shared asset library, their information is retrieved in context of a project to get the full information.\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:LcsApiProjectId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FileType\nType of file you want to list from the LCS Asset Library\n\nValid options:\n\"Model\"\n\"Process Data Package\"\n\"Software Deployable Package\"\n\"GER Configuration\"\n\"Data Package\"\n\"PowerBI Report Model\"\n\"E-Commerce Package\"\n\"NuGet Package\"\n\"Retail Self-Service Package\"\n\"Commerce Cloud Scale Unit Extension\"\n\nDefault value is \"Software Deployable Package\"\n\n```yaml\nType: LcsAssetFileType\nParameter Sets: (All)\nAliases:\nAccepted values: Model, ProcessDataPackage, SoftwareDeployablePackage, GERConfiguration, DataPackage, PowerBIReportModel, ECommercePackage, NuGetPackage, RetailSelfServicePackage, CommerceCloudScaleUnitExtension\n\nRequired: False\nPosition: 2\nDefault value: SoftwareDeployablePackage\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AssetName\nName of the asset that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-AssetName \"*ISV*\"\n\nDefault value is \"*\" which will search for all assets via the Name property\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AssetVersion\nVersion of the Asset file that you are looking for\n\nIt does a simple compare against the response from LCS and only lists the ones that matches\n\nAccepts wildcards for searching.\nE.g.\n-AssetVersion \"*ISV*\"\n\nDefault value is \"*\" which will search for all files\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AssetFilename\nName of the file that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-AssetFilename \"*ISV*\"\n\nDefault value is \"*\" which will search for all files via the FileName property\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AssetDescription\nName of the file that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-AssetDescription \"*ISV*\"\n\nDefault value is \"*\" which will search for all files via the FileDescription property\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AssetId\nId of the file that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-AssetId \"*ISV*\"\n\nDefault value is \"*\" which will search for all files via the AssetId property\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Token\n\nRequired: False\nPosition: 8\nDefault value: $Script:LcsApiBearerToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 9\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Latest\nInstruct the cmdlet to only fetch the latest file from the Asset Library from LCS\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases: GetLatest\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SkipSasGeneration\nInstruct the cmdlet to only fetch the meta data from the asset file (entry)\n\nThis is to speed up the listing of entries, in some of the larger areas in the Shared Asset Library\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RetryTimeout\nThe retry timeout, before the cmdlet should quit retrying based on the 429 status code\n\nNeeds to be provided in the timspan notation:\n\"hh:mm:ss\"\n\nhh is the number of hours, numerical notation only\nmm is the number of minutes\nss is the numbers of seconds\n\nEach section of the timeout has to valid, e.g.\nhh can maximum be 23\nmm can maximum be 59\nss can maximum be 59\n\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n\n```yaml\nType: TimeSpan\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 10\nDefault value: 00:00:00\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\nUsually this parameter is not used directly, but via the Enable-D365Exception cmdlet\nSee https://github.com/d365collaborative/d365fo.tools/wiki/Exception-handling#what-does-the--enableexception-parameter-do for further information\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Florian Hopfner (@FH-Inway)\n\n## RELATED LINKS\n\n[Get-D365LcsApiConfig]()\n\n[Get-D365LcsApiToken]()\n\n[Invoke-D365LcsApiRefreshToken]()\n\n[Set-D365LcsApiConfig]()\n\n[Get-D365LcsAssetFile]()\n\n"
  },
  {
    "path": "docs/Get-D365MaintenanceMode.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365MaintenanceMode\n\n## SYNOPSIS\nGet the maintenance mode status of the environment\n\n## SYNTAX\n\n```\nGet-D365MaintenanceMode [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>]\n [[-SqlPwd] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the maintenance mode status of the Dynamics 365 environment to make sure that things are in the correct state\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365MaintenanceMode\n```\n\nThis will get the current state of the maintenance mode of the environment\n\n## PARAMETERS\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: MaintenanceMode, Maintenance, License, Configuration, Servicing\n\nAuthor: Mötz Jensen (@splaxi)\n\n## RELATED LINKS\n\n[Enable-D365MaintenanceMode]()\n\n[Disable-D365MaintenanceMode]()\n\n"
  },
  {
    "path": "docs/Get-D365Model.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365Model\n\n## SYNOPSIS\nGet available model from Dynamics 365 Finance & Operations environment\n\n## SYNTAX\n\n```\nGet-D365Model [[-Name] <String>] [[-Module] <String>] [-CustomizableOnly] [-ExcludeMicrosoftModels]\n [-ExcludeBinaryModels] [[-BinDir] <String>] [[-PackageDirectory] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet available model from the machine running the AOS service for Dynamics 365 Finance & Operations\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365Model\n```\n\nShows the entire list of installed models located in the default location on the machine.\n\nA result set example:\n\nModelName                      Module                         IsBinary Customization        Id Publisher\n---------                      ------                         -------- -------------        -- ---------\nAccountsPayableMobile          AccountsPayableMobile          False    DoNotAllow    895571380 Microsoft Corporation\nApplicationCommon              ApplicationCommon              False    DoNotAllow      8956718 Microsoft\nApplicationFoundation          ApplicationFoundation          False    Allow               450 Microsoft Corporation\nIsvFoundation                  IsvFoundation                  True     Allow         895972027 Isv Corp\nIsvLicense                     IsvLicense                     True     DoNotAllow    895972028 Isv Corp\n\n### EXAMPLE 2\n```\nGet-D365Model -CustomizableOnly\n```\n\nShows only the models that are marked as customizable.\nWill only include models that is Customization = \"Allow\".\n\nA result set example:\n\nModelName                      Module                         IsBinary Customization        Id Publisher\n---------                      ------                         -------- -------------        -- ---------\nApplicationFoundation          ApplicationFoundation          False    Allow               450 Microsoft Corporation\nApplicationPlatform            ApplicationPlatform            False    Allow               400 Microsoft Corporation\nApplicationPlatformFormAdaptor ApplicationPlatformFormAdaptor False    Allow            855030 Microsoft Corporation\nIsvFoundation                  IsvFoundation                  True     Allow         895972027 Isv Corp\n\n### EXAMPLE 3\n```\nGet-D365Model -ExcludeMicrosoftModels\n```\n\nShows only the models that doesn't have \"Microsoft\" in the publisher.\nWill only include models that is Publisher -NotLike \"Microsoft*\".\n\nA result set example:\n\nModelName                      Module                         IsBinary Customization        Id Publisher\n---------                      ------                         -------- -------------        -- ---------\nIsvFoundation                  IsvFoundation                  True     Allow         895972027 Isv Corp\nIsvLicense                     IsvLicense                     True     DoNotAllow    895972028 Isv Corp\n\n### EXAMPLE 4\n```\nGet-D365Model -ExcludeBinaryModels\n```\n\nShows only the models that are NOT binary.\nWill only include models that is IsBinary = \"False\".\n\nA result set example:\n\nModelName                      Module                         IsBinary Customization        Id Publisher\n---------                      ------                         -------- -------------        -- ---------\nAccountsPayableMobile          AccountsPayableMobile          False    DoNotAllow    895571380 Microsoft Corporation\nApplicationCommon              ApplicationCommon              False    DoNotAllow      8956718 Microsoft\nApplicationFoundation          ApplicationFoundation          False    Allow               450 Microsoft Corporation\n\n### EXAMPLE 5\n```\nGet-D365Model -CustomizableOnly -ExcludeMicrosoftModels\n```\n\nShows only the models that are marked as customizable and NOT from Microsoft.\nWill only include models that is Customization = \"Allow\".\nWill only include models that is Publisher -NotLike \"Microsoft*\".\n\nA result set example:\n\nModelName                      Module                         IsBinary Customization        Id Publisher\n---------                      ------                         -------- -------------        -- ---------\nIsvFoundation                  IsvFoundation                  True     Allow         895972027 Isv Corp\n\n### EXAMPLE 6\n```\nGet-D365Model -Name \"Application*Adaptor\"\n```\n\nShows the list of models where the name fits the search \"Application*Adaptor\".\n\nA result set example:\n\nModelName                      Module                         IsBinary Customization        Id Publisher\n---------                      ------                         -------- -------------        -- ---------\nApplicationFoundationFormAd...\nApplicationFoundationFormAd...\nFalse    DoNotAllow       855029 Microsoft Corporation\nApplicationPlatformFormAdaptor ApplicationPlatformFormAdaptor False    Allow            855030 Microsoft Corporation\nApplicationSuiteFormAdaptor    ApplicationSuiteFormAdaptor    False    DoNotAllow       855028 Microsoft Corporation\nApplicationWorkspacesFormAd...\nApplicationWorkspacesFormAd...\nFalse    DoNotAllow       855066 Microsoft Corporation\n\n### EXAMPLE 7\n```\nGet-D365Model -Module ApplicationSuite\n```\n\nShows only the models that are inside the ApplicationSuite module.\n\nA result set example:\n\nModelName                      Module                         IsBinary Customization        Id Publisher\n---------                      ------                         -------- -------------        -- ---------\nElectronic Reporting Applic...\nApplicationSuite               False    DoNotAllow       855009 Microsoft Corporation\nFoundation                     ApplicationSuite               False    DoNotAllow           17 Microsoft Corporation\nSCMControls                    ApplicationSuite               False    DoNotAllow       855891 Microsoft Corporation\nTax Books Application Suite...\nApplicationSuite               False    DoNotAllow    895570102 Microsoft Corporation\nTax Engine Application Suit...\nApplicationSuite               False    DoNotAllow      8957001 Microsoft Corporation\n\n### EXAMPLE 8\n```\nGet-D365Model -Name \"*Application*\" -Module \"*Suite*\"\n```\n\nShows the list of models where the name fits the search \"*Application*\" and the module name fits the search \"*Suite*\".\n\nA result set example:\n\nModelName                      Module                         IsBinary Customization        Id Publisher\n---------                      ------                         -------- -------------        -- ---------\nApplicationSuiteFormAdaptor    ApplicationSuiteFormAdaptor    False    DoNotAllow       855028 Microsoft Corporation\nAtlApplicationSuite            AtlApplicationSuite            False    DoNotAllow    895972466 Microsoft Corporation\nElectronic Reporting Applic...\nApplicationSuite               False    DoNotAllow       855009 Microsoft Corporation\nTax Books Application Suite...\nApplicationSuite               False    DoNotAllow    895570102 Microsoft Corporation\nTax Engine Application Suit...\nApplicationSuite               False    DoNotAllow      8957001 Microsoft Corporation\n\n## PARAMETERS\n\n### -Name\nName of the model that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"Application*Adaptor\"\n\nDefault value is \"*\" which will search for all models\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Module\nName of the module that you want to list models from\n\nAccepts wildcards for searchinf.\nE.g.\n-Module \"Application*Adaptor\"\n\nDefault value is \"*\" which will search across all modules\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: ModuleName\n\nRequired: False\nPosition: 2\nDefault value: *\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -CustomizableOnly\nInstructs the cmdlet to filter out all models that cannot be customized\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ExcludeMicrosoftModels\nInstructs the cmdlet to exclude all models that has Microsoft as the publisher from the output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ExcludeBinaryModels\nInstruct the cmdlet to exclude binary models from the output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the AOS service PackagesLocalDirectory\\bin\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nDefault path is the same as the AOS service \"PackagesLocalDirectory\" directory\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: PackagesLocalDirectory, Servicing, Model, Models, Module, Modules\n\nAuthor: Mötz Jensen (@Splaxi)\n\nAuthor: Martin Dráb (@goshoom)\n\nThe cmdlet supports piping and can be used in advanced scenarios.\nSee more on github and the wiki pages.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365Module.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365Module\n\n## SYNOPSIS\nGet installed package / module from Dynamics 365 Finance & Operations environment\n\n## SYNTAX\n\n```\nGet-D365Module [[-Name] <String>] [-ExcludeBinaryModules] [-InDependencyOrder] [[-BinDir] <String>]\n [[-PackageDirectory] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet installed package / module from the machine running the AOS service for Dynamics 365 Finance & Operations\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365Module\n```\n\nShows the entire list of installed packages / modules located in the default location on the machine.\n\nA result set example:\n\nModuleName                               IsBinary Version         References\n----------                               -------- -------         ----------\nAccountsPayableMobile                    False    10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli...\nApplicationCommon                        False    10.0.8008.26462 {ApplicationFoundation, ApplicationPlatform}\nApplicationFoundation                    False    7.0.5493.35504  {ApplicationPlatform}\nApplicationFoundationFormAdaptor         False    7.0.4841.35227  {ApplicationPlatform, ApplicationFoundation, TestE...\nCustom                                   True     10.0.0.0        {ApplicationPlatform}\n\n### EXAMPLE 2\n```\nGet-D365Module -ExcludeBinaryModules\n```\n\nOutputs the all packages / modules that are NOT binary.\nWill only include modules that is IsBinary = \"False\".\n\nA result set example:\n\nModuleName                               IsBinary Version         References\n----------                               -------- -------         ----------\nAccountsPayableMobile                    False    10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli...\nApplicationCommon                        False    10.0.8008.26462 {ApplicationFoundation, ApplicationPlatform}\nApplicationFoundation                    False    7.0.5493.35504  {ApplicationPlatform}\nApplicationFoundationFormAdaptor         False    7.0.4841.35227  {ApplicationPlatform, ApplicationFoundation, TestE...\n\n### EXAMPLE 3\n```\nGet-D365Module -InDependencyOrder\n```\n\nReturn packages / modules in dependency order, starting with modules with no references to other modules.\n\nA result set example:\n\nModuleName                               IsBinary Version         References\n----------                               -------- -------         ----------\nApplicationPlatform                      False    7.0.0.0         {}\nApplicationFoundation                    False    7.0.0.0         {ApplicationPlatform}\nApplicationCommon                        False    10.21.36.8818   {ApplicationFoundation, ApplicationPlatform}\nAppTroubleshootingCore                   False    10.21.1136.2...\n{ApplicationCommon, ApplicationFoundation, Applica...\n\n### EXAMPLE 4\n```\nGet-D365Module -Name \"Application*Adaptor\"\n```\n\nShows the list of installed packages / modules where the name fits the search \"Application*Adaptor\".\n\nA result set example:\n\nModuleName                               IsBinary Version         References\n----------                               -------- -------         ----------\nApplicationFoundationFormAdaptor         False    7.0.4841.35227  {ApplicationPlatform, ApplicationFoundation, TestE...\nApplicationPlatformFormAdaptor           False    7.0.4841.35227  {ApplicationPlatform, TestEssentials}\nApplicationSuiteFormAdaptor              False    10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli...\nApplicationWorkspacesFormAdaptor         False    10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli...\n\n## PARAMETERS\n\n### -Name\nName of the package / module that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"Application*Adaptor\"\n\nDefault value is \"*\" which will search for all packages / modules\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ExcludeBinaryModules\nInstruct the cmdlet to exclude binary modules from the output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -InDependencyOrder\nInstructs the cmdlet to return modules in dependency order, starting with modules\nwith no references to other modules.\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases: Dependency\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the AOS service PackagesLocalDirectory\\bin\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: PackagesLocalDirectory, Servicing, Model, Models, Package, Packages\n\nAuthor: Mötz Jensen (@Splaxi)\n\nAuthor: Martin Dráb (@goshoom)\n\nThe cmdlet supports piping and can be used in advanced scenarios.\nSee more on github and the wiki pages.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365OfflineAuthenticationAdminEmail.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365OfflineAuthenticationAdminEmail\n\n## SYNOPSIS\nGets the registered offline administrator e-mail configured\n\n## SYNTAX\n\n```\nGet-D365OfflineAuthenticationAdminEmail [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the registered offline administrator from the \"DynamicsDevConfig.xml\" file located in the default Package Directory\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365OfflineAuthenticationAdminEmail\n```\n\nWill read the DynamicsDevConfig.xml and display the registered Offline Administrator E-mail address.\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Development, Email, DynamicsDevConfig, Offline, Authentication\n\nThis cmdlet is inspired by the work of \"Sheikh Sohail Hussain\" (twitter: @SSohailHussain)\n\nHis blog can be found here:\nhttp://d365technext.blogspot.com\n\nThe specific blog post that we based this cmdlet on can be found here:\nhttp://d365technext.blogspot.com/2018/07/offline-authentication-admin-email.html\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365PackageBundleDetail.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365PackageBundleDetail\n\n## SYNOPSIS\nGet the details from an axscdppkg file\n\n## SYNTAX\n\n```\nGet-D365PackageBundleDetail [-Path] <String> [[-ExtractionPath] <String>] [[-KB] <String>] [[-Hotfix] <String>]\n [-Traverse] [-KeepFiles] [-IncludeRawManifest] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the details from an axscdppkg file by extracting it like a zip file.\n\nCapable of extracting the manifest details from the inner packages as well\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365PackageBundleDetail -Path \"c:\\temp\\HotfixPackageBundle.axscdppkg\" -Traverse\n```\n\nThis will extract all the content from the \"HotfixPackageBundle.axscdppkg\" file and extract all inner packages.\nFor each inner package it will find the manifest file and fetch the KB numbers.\nThe raw manifest file content is included to be analyzed.\n\n### EXAMPLE 2\n```\nGet-D365PackageBundleDetail -Path \"c:\\temp\\HotfixPackageBundle.axscdppkg\" -ExtractionPath C:\\Temp\\20180905 -Traverse -KeepFiles\n```\n\nThis will extract all the content from the \"HotfixPackageBundle.axscdppkg\" file and extract all inner packages.\nIt will extract the content into C:\\Temp\\20180905 and keep the files after completion.\n\n### EXAMPLE 3\n```\nGet-D365PackageBundleDetail -Path C:\\temp\\HotfixPackageBundle.axscdppkg -Traverse -IncludeRawManifest\n```\n\nThis is an advanced scenario.\n\nThis will traverse the \"HotfixPackageBundle.axscdppkg\" file and will include the raw manifest file details in the output.\n\n### EXAMPLE 4\n```\nGet-D365PackageBundleDetail -Path C:\\temp\\HotfixPackageBundle.axscdppkg -Traverse -IncludeRawManifest | ForEach-Object {$_.RawManifest | Out-File \"C:\\temp\\$($_.PackageId).txt\"}\n```\n\nThis is an advanced scenario.\n\nThis will traverse the \"HotfixPackageBundle.axscdppkg\" file and save the manifest files into c:\\temp.\nEverything else is omitted and cleaned up.\n\n## PARAMETERS\n\n### -Path\nPath to the axscdppkg file you want to analyze\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ExtractionPath\nPath where you want the cmdlet to work with extraction of all the files\n\nDefault value is: C:\\Users\\Username\\AppData\\Local\\Temp\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: ([System.IO.Path]::GetTempPath())\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -KB\nKB number of the hotfix that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-KB \"4045*\"\n\nDefault value is \"*\" which will search for all KB's\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Hotfix\nPackage Id / Hotfix number the hotfix that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Hotfix \"7045*\"\n\nDefault value is \"*\" which will search for all hotfixes\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Traverse\nSwitch to instruct the cmdlet to traverse the inner packages and extract their details\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -KeepFiles\nSwitch to instruct the cmdlet to keep the files for further manual analyze\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -IncludeRawManifest\nSwitch to instruct the cmdlet to include the raw content of the manifest file\n\nOnly works with the -Traverse option\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Hotfix, KB, Manifest, HotfixPackageBundle, axscdppkg, Package, Bundle, Deployable\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365PackageLabelResourceFile.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365PackageLabelResourceFile\n\n## SYNOPSIS\nGet label / resource file from a package\n\n## SYNTAX\n\n### Default (Default)\n```\nGet-D365PackageLabelResourceFile -PackageDirectory <String> [-Name <String>] [-Language <String>]\n [<CommonParameters>]\n```\n\n### Specific\n```\nGet-D365PackageLabelResourceFile -PackageDirectory <String> [-Name <String>] [-Language <String>]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet label (resource) file from the package directory of a Dynamics 365 Finance & Operations environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365PackageLabelResourceFile -PackageDirectory \"C:\\AOSService\\PackagesLocalDirectory\\ApplicationSuite\"\n```\n\nShows all the label files for ApplicationSuite package\n\n### EXAMPLE 2\n```\nGet-D365PackageLabelResourceFile -PackageDirectory \"C:\\AOSService\\PackagesLocalDirectory\\ApplicationSuite\" -Name \"Fixed*Accounting\"\n```\n\nShows the label files for ApplicationSuite package where the name fits the search \"Fixed*Accounting\"\n\n### EXAMPLE 3\n```\nGet-D365InstalledPackage -Name \"ApplicationSuite\" | Get-D365PackageLabelResourceFile\n```\n\nShows all label files (en-US) for the ApplicationSuite package\n\n## PARAMETERS\n\n### -PackageDirectory\nPath to the directory containing the installed packages\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: Default\nAliases: Path\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n```yaml\nType: String\nParameter Sets: Specific\nAliases: Path\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Name\nName of the label (resource) file you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"Fixed*Accounting\"\n\nDefault value is \"*\" which will search for all label files\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Language\nThe language of the label file you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Language \"en*\"\n\nDefault value is \"en-US\" which will search for en-US language files\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: En-US\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: PackagesLocalDirectory, Label, Labels, Language, Development, Servicing, Module, Package, Packages\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThe cmdlet supports piping and can be used in advanced scenarios.\nSee more on github and the wiki pages.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365PackageLabelResources.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365PackageLabelResources\n\n## SYNOPSIS\nGet label from the resource file\n\n## SYNTAX\n\n### Default (Default)\n```\nGet-D365PackageLabelResources -FilePath <String> [-Name <String>] [-Value <String>] [-IncludePath]\n [<CommonParameters>]\n```\n\n### Specific\n```\nGet-D365PackageLabelResources -FilePath <String> [-Name <String>] [-Value <String>] [-IncludePath]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet label details from the resource file for a Dynamics 365 Finance & Operations environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365PackageLabelResources -Path \"C:\\AOSService\\PackagesLocalDirectory\\ApplicationSuite\\Resources\\en-US\\PRO.resources.dll\"\n```\n\nWill get all labels from the \"PRO.resouce.dll\" file\n\nThe language is determined by the path to the resource file and nothing else\n\n### EXAMPLE 2\n```\nGet-D365PackageLabelResources -Path \"C:\\AOSService\\PackagesLocalDirectory\\ApplicationSuite\\Resources\\en-US\\PRO.resources.dll\" -Name \"@PRO505\"\n```\n\nWill get the label with the name \"@PRO505\" from the \"PRO.resouce.dll\" file\n\nThe language is determined by the path to the resource file and nothing else\n\n### EXAMPLE 3\n```\nGet-D365PackageLabelResources -Path \"C:\\AOSService\\PackagesLocalDirectory\\ApplicationSuite\\Resources\\en-US\\PRO.resources.dll\" -Value \"*qty*\"\n```\n\nWill get all the labels where the value fits the search \"*qty*\" from the \"PRO.resouce.dll\" file\n\nThe language is determined by the path to the resource file and nothing else\n\n### EXAMPLE 4\n```\nGet-D365InstalledPackage -Name \"ApplicationSuite\" | Get-D365PackageLabelResourceFile -Language \"da\" | Get-D365PackageLabelResources -value \"*batch*\" -IncludePath\n```\n\nWill get all the labels, across all label files, for the \"ApplicationSuite\", where the language is \"da\" and where the label value fits the search \"*batch*\".\n\nThe path to the label file is included in the output.\n\n## PARAMETERS\n\n### -FilePath\nThe path to resource file that you want to get label details from\n\n```yaml\nType: String\nParameter Sets: Default\nAliases: Path\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n```yaml\nType: String\nParameter Sets: Specific\nAliases: Path\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Name\nName of the label you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"@PRO*\"\n\nDefault value is \"*\" which will search for all labels in the resource file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Value\nValue of the label you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"*Qty*\"\n\nDefault value is \"*\" which will search for all values in the resource file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -IncludePath\nSwitch to indicate whether you want the result set to include the path to the resource file or not\n\nDefault is OFF - path details will not be part of the output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: PackagesLocalDirectory, Label, Labels, Language, Development, Servicing, Resource, Resources\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThere are several advanced scenarios for this cmdlet.\nSee more on github and the wiki pages.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365ProductInformation.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365ProductInformation\n\n## SYNOPSIS\nReturns information about D365FO\n\n## SYNTAX\n\n```\nGet-D365ProductInformation [<CommonParameters>]\n```\n\n## DESCRIPTION\nGets detailed information about application and platform\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365ProductInformation\n```\n\nThis will get product, platform and application version details for the environment\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Build, Version, Reference, ProductVersion, ProductDetails, Product\n\nAuthor: Rasmus Andersen (@ITRasmus)\n\nThe cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations.\nThe call to the dll file gets all relevant product details for the environment.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365RsatCertificateThumbprint.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365RsatCertificateThumbprint\n\n## SYNOPSIS\nGet the thumbprint from the RSAT certificate\n\n## SYNTAX\n\n```\nGet-D365RsatCertificateThumbprint [<CommonParameters>]\n```\n\n## DESCRIPTION\nLocate the thumbprint for the certificate created during the RSAT installation\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365RsatCertificateThumbprint\n```\n\nThis will locate any certificates that has 127.0.0.1 in its name.\nIt will show the subject and the thumbprint values.\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: RSAT, Certificate, Testing, Regression Suite Automation Test, Regression, Test, Automation.\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365RsatPlaybackFile.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365RsatPlaybackFile\n\n## SYNOPSIS\nGet the RSAT playback files\n\n## SYNTAX\n\n### Default (Default)\n```\nGet-D365RsatPlaybackFile [-Path <String>] [-Name <String>] [<CommonParameters>]\n```\n\n### ExecutionUser\n```\nGet-D365RsatPlaybackFile [-Name <String>] [-ExecutionUsername <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet all the RSAT playback files from the last executions\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365RsatPlaybackFile\n```\n\nThis will get all the RSAT playback files.\nIt will search for the files in the current user AppData system folder.\n\n### EXAMPLE 2\n```\nGet-D365RsatPlaybackFile -Name *4080*\n```\n\nThis will get all the RSAT playback files which has \"4080\" as part of its name.\nIt will search for the files in the current user AppData system folder.\n\n### EXAMPLE 3\n```\nGet-D365RsatPlaybackFile -ExecutionUsername RSAT-ServiceAccount\n```\n\nThis will get all the RSAT playback files that were executed by the RSAT-ServiceAccount user.\nIt will search for the files in the RSAT-ServiceAccount user AppData system folder.\n\n## PARAMETERS\n\n### -Path\nThe path where the RSAT tool will be writing the files\n\nThe default path is:\n\"C:\\Users\\USERNAME\\AppData\\Roaming\\regressionTool\\playback\"\n\n```yaml\nType: String\nParameter Sets: Default\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:RsatplaybackPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Name\nName of Test Case that you are looking for\n\nDefault value is \"*\" which will search for all Test Cases and their corresponding files\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ExecutionUsername\nName of the user account has been running the RSAT tests on a machine that isn't the same as the current user\n\nWill enable you to log on to RSAT server that is running the tests from a console, automated, and is other account than the current user\n\n```yaml\nType: String\nParameter Sets: ExecutionUser\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: RSAT, Testing, Regression Suite Automation Test, Regression, Test, Automation, Playback\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365RsatSoapHostname.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365RsatSoapHostname\n\n## SYNOPSIS\nGet the SOAP hostname for the D365FO environment\n\n## SYNTAX\n\n```\nGet-D365RsatSoapHostname [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the SOAP hostname from the IIS configuration, to be used during the Rsat configuration\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365RsatSoapHostname\n```\n\nThis will get the SOAP hostname from IIS.\nIt will display the SOAP URL / URI correctly formatted, to be used during the configuration of Rsat.\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: RSAT, Testing, Regression Suite Automation Test, Regression, Test, Automation, SOAP\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365Runbook.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365Runbook\n\n## SYNOPSIS\nGet a Dynamics 365 Runbook\n\n## SYNTAX\n\n```\nGet-D365Runbook [[-Path] <String>] [[-Name] <String>] [-Latest] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the full path and filename of a Dynamics 365 Runbook\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365Runbook\n```\n\nThis will list all runbooks that are available in the default location.\n\n### EXAMPLE 2\n```\nGet-D365Runbook -Latest\n```\n\nThis will get the latest runbook file from the default InstallationRecords directory on the machine.\n\n### EXAMPLE 3\n```\nGet-D365Runbook -Latest | Invoke-D365RunbookAnalyzer\n```\n\nThis will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\n\n### EXAMPLE 4\n```\nGet-D365Runbook -Latest | Invoke-D365RunbookAnalyzer | Out-File \"C:\\Temp\\d365fo.tools\\runbook-analyze-results.xml\"\n```\n\nThis will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\nThe output will be saved into the \"C:\\Temp\\d365fo.tools\\runbook-analyze-results.xml\" file.\n\n### EXAMPLE 5\n```\nGet-D365Runbook | Backup-D365Runbook\n```\n\nThis will save a copy of all runbooks from the default location and save them to \"c:\\temp\\d365fo.tools\\runbookbackups\"\n\n### EXAMPLE 6\n```\nnotepad.exe (Get-D365Runbook -Latest).File\n```\n\nThis will find the latest runbook file and open it with notepad.\n\n## PARAMETERS\n\n### -Path\nPath to the folder containing the runbook files\n\nThe default path is \"InstallationRecord\" which is normally located on the \"C:\\DynamicsAX\\InstallationRecords\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: (Join-Path $Script:InstallationRecordsDir \"Runbooks\")\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### -Name\nName of the runbook file that you are looking for\n\nThe parameter accepts wildcards.\nE.g.\n-Name *hotfix-20181024*\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Latest\nInstruct the cmdlet to only get the latest runbook file, based on the last written attribute\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Runbook, Servicing, Hotfix, DeployablePackage, Deployable Package, InstallationRecordsDirectory, Installation Records Directory\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365RunbookId.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365RunbookId\n\n## SYNOPSIS\nGet runbook id\n\n## SYNTAX\n\n```\nGet-D365RunbookId [-Path] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the runbook id from inside a runbook file\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365RunbookId -Path \"C:\\DynamicsAX\\InstallationRecords\\Runbooks\\Runbook.xml\"\n```\n\nThis will inspect the Runbook.xml file and output the runbookid from inside the XML document.\n\n### EXAMPLE 2\n```\nGet-D365Runbook | Get-D365RunbookId\n```\n\nThis will find all runbook file(s) and have them analyzed by the Get-D365RunbookId cmdlet to output the runbookid(s).\n\n### EXAMPLE 3\n```\nGet-D365Runbook -Latest | Get-D365RunbookId\n```\n\nThis will find the latest runbook file and have it analyzed by the Get-D365RunbookId cmdlet to output the runbookid.\n\n## PARAMETERS\n\n### -Path\nPath to the runbook file that you want to analyse\n\nAccepts value from pipeline, also by property\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Runbook, Analyze, RunbookId, Runbooks\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365RunbookLogFile.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365RunbookLogFile\n\n## SYNOPSIS\nGet log file from a Runbook step\n\n## SYNTAX\n\n```\nGet-D365RunbookLogFile [-Path] <String> [-Step] <String> [-Latest] [-OpenInEditor] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the log files for a specific Runbook step\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365RunbookLogFile -Path \"C:\\Temp\\PU35\" -Step 34\n```\n\nThis will locate all logfiles that has been outputted from the Step 34 from the PU35 installation.\nThe output will list the complete path to the log files.\n\nAn output example:\n\nFilename     : AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log\nLastModified : 8/7/2020 12:40:34 PM\nFile         : C:\\Temp\\PU35\\RunbookWorkingFolder\\Runbook\\MININT-F36S5EH\\DIXFService\\34\\Log\\AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log\n\nFilename     : AutoUpdateDIXFService.ps1-2020-07-8--12-36-22.log\nLastModified : 8/7/2020 12:36:22 PM\nFile         : C:\\Temp\\PU35\\RunbookWorkingFolder\\Runbook\\MININT-F36S5EH\\DIXFService\\34\\Log\\AutoUpdateDIXFService.ps1-2020-07-8--12-36-22.log\n\nFilename     : AutoUpdateDIXFService.ps1-2020-05-8--19-15-07.log\nLastModified : 8/5/2020 7:15:07 PM\nFile         : C:\\Temp\\PU35\\RunbookWorkingFolder\\Runbook\\MININT-F36S5EH\\DIXFService\\34\\Log\\AutoUpdateDIXFService.ps1-2020-05-8--19-15-07.log\n\n### EXAMPLE 2\n```\nGet-D365RunbookLogFile -Path \"C:\\Temp\\PU35\" -Step 34 -Latest\n```\n\nThis will locate all logfiles that has been outputted from the Step 34 from the PU35 installation.\nThe output will be limited to the latest log, based on last write time.\nThe output will list the complete path to the log file.\n\nAn output example:\n\nFilename     : AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log\nLastModified : 8/7/2020 12:40:34 PM\nFile         : C:\\Temp\\PU35\\RunbookWorkingFolder\\Runbook\\MININT-F36S5EH\\DIXFService\\34\\Log\\AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log\n\n### EXAMPLE 3\n```\nGet-D365RunbookLogFile -Path \"C:\\Temp\\PU35\" -Step 34 -OpenInEditor\n```\n\nThis will locate all logfiles that has been outputted from the Step 34 from the PU35 installation.\nThe Get-D365RunbookLogFile will open all log files in the default text editor.\n\n### EXAMPLE 4\n```\nGet-D365RunbookLogFile -Path \"C:\\Temp\\PU35\" -Step 34 -Latest -OpenInEditor\n```\n\nThis will locate all logfiles that has been outputted from the Step 34 from the PU35 installation.\nThe output will be limited to the latest log, based on last write time.\nThe Get-D365RunbookLogFile will open the log file in the default text editor.\n\n### EXAMPLE 5\n```\nGet-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnlyAsObjects | Get-D365RunbookLogFile -Path \"C:\\Temp\\PU35\" -OpenInEditor\n```\n\nThis will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\nThe output from Invoke-D365RunbookAnalyzer will only contain failed steps.\nThe Get-D365RunbookLogFile will open all log files for the failed step.\n\n## PARAMETERS\n\n### -Path\nPath to Software Deployable Package that was run in connection with the runbook\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### -Step\nStep id for the step that you want to locate the log files for\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: StepId\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### -Latest\nInstruct the cmdlet to only work with the latest log file\n\nIs based on the last written attribute on the log file\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OpenInEditor\nInstruct the cmdlet to open the log file in the default text editor\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### System.String\n## NOTES\nTags: Runbook, Servicing, Hotfix, DeployablePackage, Deployable Package, InstallationRecordsDirectory, Installation Records Directory\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365SDPCleanUp.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365SDPCleanUp\n\n## SYNOPSIS\nGet the cleanup retention period\n\n## SYNTAX\n\n```\nGet-D365SDPCleanUp [<CommonParameters>]\n```\n\n## DESCRIPTION\nGets the configured retention period before updates are deleted\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365SDPCleanUp\n```\n\nThis will get the configured retention period from the registry\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: CleanUp, Retention, Servicing, Cut Off, DeployablePackage, Deployable Package\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThis cmdlet is based on the findings from Alex Kwitny (@AlexOnDAX)\n\nSee his blog for more info:\nhttp://www.alexondax.com/2018/04/msdyn365fo-how-to-adjust-your.html\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365SDPDetails.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365SDPDetails\n\n## SYNOPSIS\nGet details from the Software Deployable Package\n\n## SYNTAX\n\n```\nGet-D365SDPDetails [-Path] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\nDetails details about the inner modules / packages that a Software Deployable Contains\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365SDPDetails -Path 'C:\\Temp\\RV-10.0.36.44.zip'\n```\n\nThis will display the basic details about the package.\nThe package is a zip file.\n\nA result set example:\n\nPlatform PlatformVersion Modules\n-------- --------------- -------\nUpdate55 7.0.6651.92     {@{Name=RapidValue; Version=7.0.6651.92}, @{Name=TCLCommon; Version=7.0.6651.92}, @{Name=TC...\n\n### EXAMPLE 2\n```\nGet-D365SDPDetails -Path 'C:\\Temp\\RV-10.0.36.44'\n```\n\nThis will display the basic details about the package.\nThe package is extracted to a local folder.\n\nA result set example:\n\nPlatform PlatformVersion Modules\n-------- --------------- -------\nUpdate55 7.0.6651.92     {@{Name=RapidValue; Version=7.0.6651.92}, @{Name=TCLCommon; Version=7.0.6651.92}, @{Name=TC...\n\n### EXAMPLE 3\n```\nGet-D365SDPDetails -Path 'C:\\Temp\\RV-10.0.36.44.zip' | Select-Object -ExpandProperty Modules\n```\n\nThis will display the module details that are part of the package.\nThe package is a zip file.\n\nA result set example:\n\nName       Version\n----       -------\nRapidValue 7.0.6651.92\nTCLCommon  7.0.6651.92\nTCLLabel   7.0.6651.92\n\n## PARAMETERS\n\n### -Path\nPath to the Software Deployable Package that you want to work against\n\nThe cmdlet supports a path to a zip-file or directory with the unpacked content\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365Table.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365Table\n\n## SYNOPSIS\nGet a table\n\n## SYNTAX\n\n### Default (Default)\n```\nGet-D365Table [[-Name] <String[]>] [[-DatabaseServer] <String>] [[-DatabaseName] <String>]\n [[-SqlUser] <String>] [[-SqlPwd] <String>] [<CommonParameters>]\n```\n\n### TableId\n```\nGet-D365Table [-Id] <Int32> [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>]\n [[-SqlPwd] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet a table either by TableName (wildcard search allowed) or by TableId\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365Table -Name CustTable\n```\n\nWill get the details for the CustTable\n\n### EXAMPLE 2\n```\nGet-D365Table -Id 10347\n```\n\nWill get the details for the table with the id 10347.\n\n## PARAMETERS\n\n### -Name\nName of the table that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"Cust*\"\n\nDefault value is \"*\" which will search for all tables\n\n```yaml\nType: String[]\nParameter Sets: Default\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Id\nThe specific id for the table you are looking for\n\n```yaml\nType: Int32\nParameter Sets: TableId\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: 0\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Table, Tables, AOT, TableId, Development\n\nAuthor: Mötz Jensen (@splaxi)\n\nThe cmdlet supports piping and can be used in advanced scenarios.\nSee more on github and the wiki pages.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365TableField.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365TableField\n\n## SYNOPSIS\nGet a field from table\n\n## SYNTAX\n\n### Default (Default)\n```\nGet-D365TableField [-TableId] <Int32> [[-Name] <String>] [[-FieldId] <Int32>] [[-DatabaseServer] <String>]\n [[-DatabaseName] <String>] [[-SqlUser] <String>] [[-SqlPwd] <String>] [-IncludeTableDetails]\n [<CommonParameters>]\n```\n\n### SearchByNameForce\n```\nGet-D365TableField [[-Name] <String>] [[-DatabaseServer] <String>] [[-DatabaseName] <String>]\n [[-SqlUser] <String>] [[-SqlPwd] <String>] [-SearchAcrossTables] [<CommonParameters>]\n```\n\n### TableName\n```\nGet-D365TableField [[-Name] <String>] [[-FieldId] <Int32>] [[-DatabaseServer] <String>]\n [[-DatabaseName] <String>] [[-SqlUser] <String>] [[-SqlPwd] <String>] [-TableName] <String>\n [-IncludeTableDetails] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet a field either by FieldName (wildcard search allowed) or by FieldId\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365TableField -TableId 10347\n```\n\nWill get all field details for the table with id 10347.\n\n### EXAMPLE 2\n```\nGet-D365TableField -TableName CustTable\n```\n\nWill get all field details for the CustTable table.\n\n### EXAMPLE 3\n```\nGet-D365TableField -TableId 10347 -FieldId 175\n```\n\nWill get the details for the field with id 175 that belongs to the table with id 10347.\n\n### EXAMPLE 4\n```\nGet-D365TableField -TableId 10347 -Name \"VATNUM\"\n```\n\nWill get the details for the \"VATNUM\" that belongs to the table with id 10347.\n\n### EXAMPLE 5\n```\nGet-D365TableField -TableId 10347 -Name \"VAT*\"\n```\n\nWill get the details for all fields that fits the search \"VAT*\" that belongs to the table with id 10347.\n\n### EXAMPLE 6\n```\nGet-D365TableField -Name AccountNum -SearchAcrossTables\n```\n\nWill search for the AccountNum field across all tables.\n\n### EXAMPLE 7\n```\nGet-D365TableField -TableName CustTable -IncludeTableDetails\n```\n\nWill get all field details for the CustTable table.\nWill include table details in the output.\n\n## PARAMETERS\n\n### -TableId\nThe id of the table that the field belongs to\n\n```yaml\nType: Int32\nParameter Sets: Default\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: 0\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Name\nName of the field that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"Account*\"\n\nDefault value is \"*\" which will search for all fields\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FieldId\nId of the field that you are looking for\n\nType is integer\n\n```yaml\nType: Int32\nParameter Sets: Default, TableName\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: 0\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 8\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -TableName\nName of the table that the field belongs to\n\nSearch will only return the first hit (unordered) and work against that hit\n\n```yaml\nType: String\nParameter Sets: TableName\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -IncludeTableDetails\nSwitch options to enable the result set to include extended details\n\n```yaml\nType: SwitchParameter\nParameter Sets: Default, TableName\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SearchAcrossTables\nSwitch options to force the cmdlet to search across all tables when looking for the field\n\n```yaml\nType: SwitchParameter\nParameter Sets: SearchByNameForce\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Table, Tables, Fields, TableField, Table Field, TableName, TableId\n\nAuthor: Mötz Jensen (@splaxi)\n\nThe cmdlet supports piping and can be used in advanced scenarios.\nSee more on github and the wiki pages.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365TableSequence.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365TableSequence\n\n## SYNOPSIS\nGet the sequence object for table\n\n## SYNTAX\n\n```\nGet-D365TableSequence [[-TableName] <String>] [[-DatabaseServer] <String>] [[-DatabaseName] <String>]\n [[-SqlUser] <String>] [[-SqlPwd] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the sequence details for tables\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365TableSequence | Format-Table\n```\n\nThis will get all the sequence details for all tables inside the database.\nIt will format the output as a table for better overview.\n\n### EXAMPLE 2\n```\nGet-D365TableSequence -TableName \"Custtable\" | Format-Table\n```\n\nThis will get the sequence details for the CustTable in the database.\nIt will format the output as a table for better overview.\n\n### EXAMPLE 3\n```\nGet-D365TableSequence -TableName \"Cust*\" | Format-Table\n```\n\nThis will get the sequence details for all tables that matches the search \"Cust*\" in the database.\nIt will format the output as a table for better overview.\n\n### EXAMPLE 4\n```\nGet-D365Table -Name CustTable | Get-D365TableSequence | Format-Table\n```\n\nThis will get the table details from the Get-D365Table cmdlet and pipe that into Get-D365TableSequence.\nThis will get the sequence details for the CustTable in the database.\nIt will format the output as a table for better overview.\n\n## PARAMETERS\n\n### -TableName\nName of the table that you want to work against\n\nAccepts wildcards for searching.\nE.g.\n-TableName \"Cust*\"\n\nDefault value is \"*\" which will search for all tables\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Name\n\nRequired: False\nPosition: 2\nDefault value: *\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Table, RecId, Sequence, Record Id\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365TablesInChangedTracking.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365TablesInChangedTracking\n\n## SYNOPSIS\nGet table that is taking part of Change Tracking\n\n## SYNTAX\n\n```\nGet-D365TablesInChangedTracking [[-Name] <String>] [[-DatabaseServer] <String>] [[-DatabaseName] <String>]\n [[-SqlUser] <String>] [[-SqlPwd] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet table(s) that is taking part of the SQL Server Change Tracking mechanism\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365TablesInChangedTracking\n```\n\nThis will list all tables that are taking part in the SQL Server Change Tracking.\n\n### EXAMPLE 2\n```\nGet-D365TablesInChangedTracking -Name CustTable\n```\n\nThis will search for a table in the list of tables that are taking part in the SQL Server Change Tracking.\nIt will use the CustTable as the search pattern while searching for the table.\n\n## PARAMETERS\n\n### -Name\nName of the table that you are looking for\n\nAccepts wildcards for searching.\nE.g.\n-Name \"Cust*\"\n\nDefault value is \"*\" which will search for all tables\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Table, Change Tracking, Tablename, DMF, DIXF\n\nAuthor: Mötz Jensen (@splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365TfsUri.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365TfsUri\n\n## SYNOPSIS\nGet the TFS / VSTS registered URL / URI\n\n## SYNTAX\n\n```\nGet-D365TfsUri [[-Path] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGets the URI from the configuration of the local tfs connection in visual studio\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365TfsUri\n```\n\nThis will invoke the default tf.exe client located in the Visual Studio 2015 directory\nand fetch the configured URI.\n\n## PARAMETERS\n\n### -Path\nPath to the tf.exe file that the cmdlet will invoke\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:TfDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: TFS, VSTS, URL, URI, Servicing, Development\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365TfsWorkspace.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365TfsWorkspace\n\n## SYNOPSIS\nGet the TFS / VSTS registered workspace path\n\n## SYNTAX\n\n```\nGet-D365TfsWorkspace [[-Path] <String>] [[-TfsUri] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGets the workspace path from the configuration of the local tfs in visual studio\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365TfsWorkspace -TfsUri https://PROJECT.visualstudio.com\n```\n\nThis will invoke the default tf.exe client located in the Visual Studio 2015 directory\nand fetch the configured URI.\n\n## PARAMETERS\n\n### -Path\nPath to the directory where the Team Foundation Client executable is located\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:TfDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -TfsUri\nUri to the TFS / VSTS that the workspace is connected to\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:TfsUri\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: TFS, VSTS, URL, URI, Servicing, Development\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365Url.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365Url\n\n## SYNOPSIS\nGet the url for accessing the instance\n\n## SYNTAX\n\n```\nGet-D365Url [-Force] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the complete URL for accessing the Dynamics 365 Finance & Operations instance running on this machine\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365Url\n```\n\nThis will get the correct URL to access the environment\n\n## PARAMETERS\n\n### -Force\nSwitch to instruct the cmdlet to retrieve the name from the system files\ninstead of the name stored in memory after loading this module.\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: URL, URI, Servicing\n\nAuthor: Rasmus Andersen (@ITRasmus)\n\nThe cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations.\nThe call to the dll file gets all registered URL for the environment.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365User.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365User\n\n## SYNOPSIS\nGet users from the environment\n\n## SYNTAX\n\n```\nGet-D365User [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>] [[-SqlPwd] <String>]\n [[-Email] <String>] [-ExcludeSystemUsers] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet all relevant user details from the Dynamics 365 for Finance & Operations\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365User\n```\n\nThis will get all users from the environment.\n\n### EXAMPLE 2\n```\nGet-D365User -ExcludeSystemUsers\n```\n\nThis will get all users from the environment, but filter out all known system user accounts.\n\n### EXAMPLE 3\n```\nGet-D365User -Email \"*contoso.com\"\n```\n\nThis will search for all users with an e-mail address containing 'contoso.com' from the environment.\n\n## PARAMETERS\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Email\nThe search string to select which user(s) should be updated\n\nThe parameter supports wildcards.\nE.g.\n-Email \"*@contoso.com*\"\n\nDefault value is \"*\" to get all users\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ExcludeSystemUsers\nInstructs the cmdlet to filter out all known system users\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: User, Users\n\nAuthor: Mötz Jensen (@Splaxi)\nAuthor: Rasmus Andersen (@ITRasmus)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365UserAuthenticationDetail.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365UserAuthenticationDetail\n\n## SYNOPSIS\nCmdlet used to get authentication details about a user\n\n## SYNTAX\n\n```\nGet-D365UserAuthenticationDetail [-Email] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\nThe cmdlet will take the e-mail parameter and use it to lookup all the needed details for configuring authentication against Dynamics 365 Finance & Operations\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365UserAuthenticationDetail -Email \"Claire@contoso.com\"\n```\n\nThis will get all the authentication details for the user account with the email address \"Claire@contoso.com\"\n\n## PARAMETERS\n\n### -Email\nThe e-mail address / login name of the user that the cmdlet must gather details about\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByValue)\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: User, Users, Security, Configuration, Authentication\n\nAuthor : Rasmus Andersen (@ITRasmus)\nAuthor : Mötz Jensen (@splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365VisualStudioCompilerResult.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365VisualStudioCompilerResult\n\n## SYNOPSIS\nGet the compiler outputs presented\n\n## SYNTAX\n\n```\nGet-D365VisualStudioCompilerResult [[-Module] <String>] [-ErrorsOnly] [-OutputTotals] [-OutputAsObjects]\n [[-PackageDirectory] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the Visual Studio compiler outputs presented in a structured manner on the screen\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365VisualStudioCompilerResult\n```\n\nThis will return the compiler output for all modules.\n\nA result set example:\n\nFile                                                                                     Warnings Errors\n----                                                                                     -------- ------\nK:\\AosService\\PackagesLocalDirectory\\ApplicationCommon\\BuildModelResult.log                    55      0\nK:\\AosService\\PackagesLocalDirectory\\ApplicationFoundation\\BuildModelResult.log               692      0\nK:\\AosService\\PackagesLocalDirectory\\ApplicationPlatform\\BuildModelResult.log                 155      0\nK:\\AosService\\PackagesLocalDirectory\\ApplicationSuite\\BuildModelResult.log                  10916      0\nK:\\AosService\\PackagesLocalDirectory\\CustomModule\\BuildModelResult.log                          1      2\n\n### EXAMPLE 2\n```\nGet-D365VisualStudioCompilerResult -ErrorsOnly\n```\n\nThis will return the compiler output for all modules where there was errors in.\n\nA result set example:\n\nFile                                                                                     Warnings Errors\n----                                                                                     -------- ------\nK:\\AosService\\PackagesLocalDirectory\\CustomModule\\BuildModelResult.log                          1      2\n\n### EXAMPLE 3\n```\nGet-D365VisualStudioCompilerResult -ErrorsOnly -OutputAsObjects\n```\n\nThis will return the compiler output for all modules where there was errors in.\nThe output will be PSObjects, which can be assigned to a variable and used for futher analysis.\n\nA result set example:\n\nFile                                                                                     Warnings Errors\n----                                                                                     -------- ------\nK:\\AosService\\PackagesLocalDirectory\\CustomModule\\BuildModelResult.log                          1      2\n\n### EXAMPLE 4\n```\nGet-D365VisualStudioCompilerResult -OutputTotals\n```\n\nThis will return the compiler output for all modules and write a total overview to the console.\n\nA result set example:\n\nFile                                                                                     Warnings Errors\n----                                                                                     -------- ------\nK:\\AosService\\PackagesLocalDirectory\\ApplicationCommon\\BuildModelResult.log                    55      0\nK:\\AosService\\PackagesLocalDirectory\\ApplicationFoundation\\BuildModelResult.log               692      0\nK:\\AosService\\PackagesLocalDirectory\\ApplicationPlatform\\BuildModelResult.log                 155      0\nK:\\AosService\\PackagesLocalDirectory\\ApplicationSuite\\BuildModelResult.log                  10916      0\nK:\\AosService\\PackagesLocalDirectory\\CustomModule\\BuildModelResult.log                          1      2\n\n\nTotal Errors: 2\nTotal Warnings: 11819\n\n## PARAMETERS\n\n### -Module\nName of the module that you want to work against\n\nDefault value is \"*\" which will search for all modules\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: ModuleName\n\nRequired: False\nPosition: 1\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ErrorsOnly\nInstructs the cmdlet to only output compile results where there was errors detected\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputTotals\nInstructs the cmdlet to output the total errors and warnings after the analysis\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputAsObjects\nInstructs the cmdlet to output the objects instead of formatting them\n\nIf you don't assign the output, it will be formatted the same way as the original output, but without the coloring of the column values\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nDefault path is the same as the AOS service \"PackagesLocalDirectory\" directory\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### [PsCustomObject]\n## NOTES\nTags: Compiler, Build, Errors, Warnings, Tasks\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThis cmdlet is inspired by the work of \"Vilmos Kintera\" (twitter: @DAXRunBase)\n\nAll credits goes to him for showing how to extract these information\n\nHis blog can be found here:\nhttps://www.daxrunbase.com/blog/\n\nThe specific blog post that we based this cmdlet on can be found here:\nhttps://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/\n\nThe github repository containing the original scrips can be found here:\nhttps://github.com/DAXRunBase/PowerShell-and-Azure\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365WebServerType.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365WebServerType\n\n## SYNOPSIS\nGet the default web server to be used\n\n## SYNTAX\n\n```\nGet-D365WebServerType [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet the web server which will be used to run D365FO: Either IIS or IIS Express.\nNewly deployed development machines will have this set to IIS Express by default.\n\nIt will look for the file located in the default Package Directory.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365WebServerType\n```\n\nThis will display the current web server type registered in the \"DynamicsDevConfig.xml\" file.\nLocated in \"K:\\AosService\\PackagesLocalDirectory\\bin\".\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTag: Web Server, IIS, IIS Express, Development\n\nAuthor: Sander Holvoet (@smholvoet)\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Get-D365WindowsActivationStatus.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Get-D365WindowsActivationStatus\n\n## SYNOPSIS\nGet activation status\n\n## SYNTAX\n\n```\nGet-D365WindowsActivationStatus [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet all the important license and activation information from the machine\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nGet-D365WindowsActivationStatus\n```\n\nThis will get the remaining grace and rearm activation information for the machine\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Windows, License, Activation, Arm, Rearm\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThe cmdlet uses CIM objects to access the activation details\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Import-D365AadApplication.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Import-D365AadApplication\n\n## SYNOPSIS\nUsed to import Aad applications into D365FO\n\n## SYNTAX\n\n```\nImport-D365AadApplication [-Name] <String> [-UserId] <String> [-ClientId] <String> [[-DatabaseServer] <String>]\n [[-DatabaseName] <String>] [[-SqlUser] <String>] [[-SqlPwd] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nProvides a method for importing a AAD application into D365FO.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nImport-D365AadApplication -Name \"Application1\" -UserId \"admin\" -ClientId \"aef2e67c-64a3-4c72-9294-d288c5bf503d\"\n```\n\nImports Application1 as an application linked to user admin into the D365FO environment.\n\n## PARAMETERS\n\n### -Name\nThe name that the imported application should have inside the D365FO environment\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -UserId\nThe id of the user linked to the application inside the D365FO environment\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ClientId\nThe Client ID that the imported application should use inside the D365FO environment\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: User, Users, Security, Configuration, Permission, AAD, Azure Active Directory, Group, Groups\n\nAuthor: Gert Van Der Heyden (@gertvdheyden)\n\nAt no circumstances can this cmdlet be used to import users into a PROD environment.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Import-D365AadUser.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Import-D365AadUser\n\n## SYNOPSIS\nUsed to import Aad users into D365FO\n\n## SYNTAX\n\n### UserListImport (Default)\n```\nImport-D365AadUser [-Users] <String[]> [[-StartupCompany] <String>] [[-DatabaseServer] <String>]\n [[-DatabaseName] <String>] [[-SqlUser] <String>] [[-SqlPwd] <String>] [[-IdPrefix] <String>]\n [[-NameSuffix] <String>] [[-IdValue] <String>] [[-NameValue] <String>] [[-AzureAdCredential] <PSCredential>]\n [-SkipAzureAd] [[-EmailValue] <String>] [[-TenantId] <String>] [<CommonParameters>]\n```\n\n### GroupNameImport\n```\nImport-D365AadUser [-AadGroupName] <String> [[-StartupCompany] <String>] [[-DatabaseServer] <String>]\n [[-DatabaseName] <String>] [[-SqlUser] <String>] [[-SqlPwd] <String>] [[-IdPrefix] <String>]\n [[-NameSuffix] <String>] [[-IdValue] <String>] [[-NameValue] <String>] [[-AzureAdCredential] <PSCredential>]\n [-ForceExactAadGroupName] [[-EmailValue] <String>] [[-TenantId] <String>] [<CommonParameters>]\n```\n\n### GroupIdImport\n```\nImport-D365AadUser [[-StartupCompany] <String>] [[-DatabaseServer] <String>] [[-DatabaseName] <String>]\n [[-SqlUser] <String>] [[-SqlPwd] <String>] [[-IdPrefix] <String>] [[-NameSuffix] <String>]\n [[-IdValue] <String>] [[-NameValue] <String>] [[-AzureAdCredential] <PSCredential>] [-AadGroupId] <String>\n [[-EmailValue] <String>] [[-TenantId] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nProvides a method for importing a AAD UserGroup or a comma separated list of AadUsers into D365FO.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nImport-D365AadUser -Users \"Claire@contoso.com\",\"Allen@contoso.com\"\n```\n\nImports Claire and Allen as users\n\n### EXAMPLE 2\n```\n$myPassword = ConvertTo-SecureString \"MyPasswordIsSecret\" -AsPlainText -Force\n```\n\nPS C:\\\\\\> $myCredentials = New-Object System.Management.Automation.PSCredential (\"MyEmailIsAlso\", $myPassword)\n\nPS C:\\\\\\> Import-D365AadUser -Users \"Claire@contoso.com\",\"Allen@contoso.com\" -AzureAdCredential $myCredentials\n\nThis will import Claire and Allen as users.\n\n### EXAMPLE 3\n```\nImport-D365AadUser -AadGroupName \"CustomerTeam1\"\n```\n\nif more than one group match the AadGroupName, you can use the ExactAadGroupName parameter\nImport-D365AadUser -AadGroupName \"CustomerTeam1\" -ForceExactAadGroupName\n\n### EXAMPLE 4\n```\nImport-D365AadUser -AadGroupName \"CustomerTeam1\" -ForceExactAadGroupName\n```\n\nThis is used to force the cmdlet to find the exact named group in Azure Active Directory.\n\n### EXAMPLE 5\n```\nImport-D365AadUser -AadGroupId \"99999999-aaaa-bbbb-cccc-9999999999\"\n```\n\nImports all the users that is present in the AAD Group called CustomerTeam1\n\n### EXAMPLE 6\n```\nImport-D365AadUser -Users \"Claire@contoso.com\",\"Allen@contoso.com\" -SkipAzureAd\n```\n\nImports Claire and Allen as users.\nWill NOT make you connect to the Azure Active Directory(AAD).\nThe needed details will be based on the e-mail address only, and the rest will be blanked.\n\n### EXAMPLE 7\n```\nImport-D365AadUser -Users \"Claire@contoso.com\",\"Allen@contoso.com\" -TenantId \"99999999-aaaa-bbbb-cccc-9999999999\"\n```\n\nImports Claire and Allen as users.\nUses tenant id \"99999999-aaaa-bbbb-cccc-9999999999\"\nwhen connecting to Azure Active Directory(AAD).\n\n## PARAMETERS\n\n### -AadGroupName\nAzure Active directory user group containing users to be imported\n\n```yaml\nType: String\nParameter Sets: GroupNameImport\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Users\nArray of users that you want to import into the D365FO environment\n\n```yaml\nType: String[]\nParameter Sets: UserListImport\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -StartupCompany\nStartup company of users imported.\n\nDefault is DAT\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: DAT\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -IdPrefix\nA text that will be prefixed into the ID field.\nE.g.\n-IdPrefix \"EXT-\" will import users and set ID starting with \"EXT-...\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 8\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -NameSuffix\nA text that will be suffixed into the NAME field.\nE.g.\n-NameSuffix \"(Contoso)\" will import users and append \"(Contoso)\"\" to the NAME\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 9\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -IdValue\nSpecify which field to use as ID value when importing the users.\nAvailable options 'Login' / 'FirstName' / 'UserPrincipalName'\n\nDefault is 'Login'\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 10\nDefault value: Login\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -NameValue\nSpecify which field to use as NAME value when importing the users.\nAvailable options 'FirstName' / 'DisplayName'\n\nDefault is 'DisplayName'\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 11\nDefault value: DisplayName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AzureAdCredential\nUse a PSCredential object for connecting with AzureAd\n\n```yaml\nType: PSCredential\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 12\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SkipAzureAd\nSwitch to instruct the cmdlet to skip validating against the Azure Active Directory\n\n```yaml\nType: SwitchParameter\nParameter Sets: UserListImport\nAliases:\n\nRequired: False\nPosition: 13\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ForceExactAadGroupName\nForce to find the exact name of the Azure Active Directory Group\n\n```yaml\nType: SwitchParameter\nParameter Sets: GroupNameImport\nAliases:\n\nRequired: False\nPosition: 14\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AadGroupId\nAzure Active directory user group ID containing users to be imported\n\n```yaml\nType: String\nParameter Sets: GroupIdImport\nAliases:\n\nRequired: True\nPosition: 15\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EmailValue\nSpecify which field to use as EMAIL value when importing the users.\nAvailable options 'Mail' / 'UserPrincipalName'\n\nDefault is 'Mail'\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 16\nDefault value: Mail\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -TenantId\nThe TenantId to use when connecting to Azure Active Directory\n\nUses the tenant id of the current environment if not specified.\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 17\nDefault value: $Script:TenantId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: User, Users, Security, Configuration, Permission, AAD, Azure Active Directory, Group, Groups\n\nAuthor: Rasmus Andersen (@ITRasmus)\nAuthor: Charles Colombel (@dropshind)\nAuthor: Mötz Jensen (@Splaxi)\nAuthor: Miklós Molnár (@scifimiki)\nAuthor: Gert Van der Heyden (@gertvdh)\nAuthor: Florian Hopfner (@FH-Inway)\n\nAt no circumstances can this cmdlet be used to import users into a PROD environment.\n\nOnly users from an Azure Active Directory that you have access to, can be imported.\nUse AAD B2B implementation if you want to support external people.\n\nEvery imported users will get the System Administration / Administrator role assigned on import\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Import-D365Bacpac.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Import-D365Bacpac\n\n## SYNOPSIS\nImport a bacpac file\n\n## SYNTAX\n\n### ImportTier1 (Default)\n```\nImport-D365Bacpac [-ImportModeTier1] [[-DatabaseServer] <String>] [[-DatabaseName] <String>]\n [[-SqlUser] <String>] [[-SqlPwd] <String>] [-BacpacFile] <String> [-NewDatabaseName] <String>\n [-CustomSqlFile <String>] [-ModelFile <String>] [-DiagnosticFile <String>] [-ImportOnly]\n [-MaxParallelism <Int32>] [-LogPath <String>] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException]\n [-Properties <String[]>] [<CommonParameters>]\n```\n\n### ImportOnlyTier2\n```\nImport-D365Bacpac [-ImportModeTier2] [[-DatabaseServer] <String>] [[-DatabaseName] <String>]\n [-SqlUser] <String> [-SqlPwd] <String> [-BacpacFile] <String> [-NewDatabaseName] <String>\n [[-AxDeployExtUserPwd] <String>] [[-AxDbAdminPwd] <String>] [[-AxRuntimeUserPwd] <String>]\n [[-AxMrRuntimeUserPwd] <String>] [[-AxRetailRuntimeUserPwd] <String>] [[-AxRetailDataSyncUserPwd] <String>]\n [[-AxDbReadonlyUserPwd] <String>] [-CustomSqlFile <String>] [-ModelFile <String>] [-DiagnosticFile <String>]\n [-ImportOnly] [-MaxParallelism <Int32>] [-LogPath <String>] [-ShowOriginalProgress] [-OutputCommandOnly]\n [-EnableException] [-Properties <String[]>] [<CommonParameters>]\n```\n\n### ImportTier2\n```\nImport-D365Bacpac [-ImportModeTier2] [[-DatabaseServer] <String>] [[-DatabaseName] <String>]\n [-SqlUser] <String> [-SqlPwd] <String> [-BacpacFile] <String> [-NewDatabaseName] <String>\n [-AxDeployExtUserPwd] <String> [-AxDbAdminPwd] <String> [-AxRuntimeUserPwd] <String>\n [-AxMrRuntimeUserPwd] <String> [-AxRetailRuntimeUserPwd] <String> [-AxRetailDataSyncUserPwd] <String>\n [-AxDbReadonlyUserPwd] <String> [-CustomSqlFile <String>] [-ModelFile <String>] [-DiagnosticFile <String>]\n [-MaxParallelism <Int32>] [-LogPath <String>] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException]\n [-Properties <String[]>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nImport a bacpac file to either a Tier1 or Tier2 environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365InstallSqlPackage\n```\n\nYou should always install the latest version of the SqlPackage.exe, which is used by New-D365Bacpac.\n\nThis will fetch the latest .Net Core Version of SqlPackage.exe and install it at \"C:\\temp\\d365fo.tools\\SqlPackage\".\n\n### EXAMPLE 2\n```\nImport-D365Bacpac -ImportModeTier1 -BacpacFile \"C:\\temp\\uat.bacpac\" -NewDatabaseName \"ImportedDatabase\"\n```\n\nPS C:\\\\\\> Switch-D365ActiveDatabase -NewDatabaseName \"ImportedDatabase\"\n\nThis will instruct the cmdlet that the import will be working against a SQL Server instance.\nIt will import the \"C:\\temp\\uat.bacpac\" file into a new database named \"ImportedDatabase\".\nThe next thing to do is to switch the active database out with the new one you just imported.\n\"ImportedDatabase\" will be switched in as the active database, while the old one will be named \"AXDB_original\".\n\n### EXAMPLE 3\n```\nImport-D365Bacpac -ImportModeTier2 -SqlUser \"sqladmin\" -SqlPwd \"XyzXyz\" -BacpacFile \"C:\\temp\\uat.bacpac\" -AxDeployExtUserPwd \"XxXx\" -AxDbAdminPwd \"XxXx\" -AxRuntimeUserPwd \"XxXx\" -AxMrRuntimeUserPwd \"XxXx\" -AxRetailRuntimeUserPwd \"XxXx\" -AxRetailDataSyncUserPwd \"XxXx\" -AxDbReadonlyUserPwd \"XxXx\" -NewDatabaseName \"ImportedDatabase\"\n```\n\nPS C:\\\\\\> Switch-D365ActiveDatabase -NewDatabaseName \"ImportedDatabase\" -SqlUser \"sqladmin\" -SqlPwd \"XyzXyz\"\n\nThis will instruct the cmdlet that the import will be working against an Azure DB instance.\nIt requires all relevant passwords from LCS for all the builtin user accounts used in a Tier 2 environment.\nIt will import the \"C:\\temp\\uat.bacpac\" file into a new database named \"ImportedDatabase\".\nThe next thing to do is to switch the active database out with the new one you just imported.\n\"ImportedDatabase\" will be switched in as the active database, while the old one will be named \"AXDB_original\".\n\n### EXAMPLE 4\n```\nImport-D365Bacpac -ImportModeTier1 -BacpacFile \"C:\\temp\\uat.bacpac\" -NewDatabaseName \"ImportedDatabase\" -DiagnosticFile \"C:\\temp\\ImportLog.txt\"\n```\n\nThis will instruct the cmdlet that the import will be working against a SQL Server instance.\nIt will import the \"C:\\temp\\uat.bacpac\" file into a new database named \"ImportedDatabase\".\nIt will output a diagnostic file to \"C:\\temp\\ImportLog.txt\".\n\n### EXAMPLE 5\n```\nImport-D365Bacpac -ImportModeTier1 -BacpacFile \"C:\\temp\\uat.bacpac\" -NewDatabaseName \"ImportedDatabase\" -DiagnosticFile \"C:\\temp\\ImportLog.txt\" -MaxParallelism 32\n```\n\nThis will instruct the cmdlet that the import will be working against a SQL Server instance.\nIt will import the \"C:\\temp\\uat.bacpac\" file into a new database named \"ImportedDatabase\".\nIt will output a diagnostic file to \"C:\\temp\\ImportLog.txt\".\n\nIt will use 32 connections against the database server while importing the bacpac file.\n\n### EXAMPLE 6\n```\nImport-D365Bacpac -ImportModeTier1 -BacpacFile \"C:\\temp\\uat.bacpac\" -NewDatabaseName \"ImportedDatabase\" -ImportOnly\n```\n\nThis will instruct the cmdlet that the import will be working against a SQL Server instance.\nIt will import the \"C:\\temp\\uat.bacpac\" file into a new database named \"ImportedDatabase\".\nNo cleanup or prepping jobs will be executed, because this is for importing only.\n\nThis would be something that you can use when extract a bacpac file from a Tier1 and want to import it into a Tier1.\nYou would still need to execute the Switch-D365ActiveDatabase cmdlet, to get the newly imported database to be the AXDB database.\n\n### EXAMPLE 7\n```\n[System.Collections.ArrayList] $PropertiesList = New-Object -TypeName \"System.Collections.ArrayList\"\n```\n\nPS C:\\\\\\> $PropertiesList.Add(\"DisableIndexesForDataPhase=false\")\nPS C:\\\\\\> Import-D365Bacpac -ImportModeTier1 -BacpacFile \"C:\\temp\\uat.bacpac\" -NewDatabaseName \"ImportedDatabase\" -Properties $PropertiesList.ToArray()\n\nThis will instruct the cmdlet that the import will be working against a SQL Server instance.\nIt will import the \"C:\\temp\\uat.bacpac\" file into a new database named \"ImportedDatabase\".\nIt will use the DisableIndexesForDataPhase SQLPackage property to disable the index rebuild during the data phase of the import.\n\n## PARAMETERS\n\n### -ImportModeTier1\nSwitch to instruct the cmdlet that it will import into a Tier1 environment\n\nThe cmdlet will expect to work against a SQL Server instance\n\n```yaml\nType: SwitchParameter\nParameter Sets: ImportTier1\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ImportModeTier2\nSwitch to instruct the cmdlet that it will import into a Tier2 environment\n\nThe cmdlet will expect to work against an Azure DB instance\n\n```yaml\nType: SwitchParameter\nParameter Sets: ImportOnlyTier2, ImportTier2\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: ImportTier1\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n```yaml\nType: String\nParameter Sets: ImportOnlyTier2, ImportTier2\nAliases:\n\nRequired: True\nPosition: 4\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: ImportTier1\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n```yaml\nType: String\nParameter Sets: ImportOnlyTier2, ImportTier2\nAliases:\n\nRequired: True\nPosition: 5\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BacpacFile\nPath to the bacpac file you want to import into the database server\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File\n\nRequired: True\nPosition: 6\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -NewDatabaseName\nName of the new database that will be created while importing the bacpac file\n\nThis will create a new database on the database server and import the content of the bacpac into\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 7\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AxDeployExtUserPwd\nPassword that is obtained from LCS\n\n```yaml\nType: String\nParameter Sets: ImportOnlyTier2\nAliases:\n\nRequired: False\nPosition: 8\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n```yaml\nType: String\nParameter Sets: ImportTier2\nAliases:\n\nRequired: True\nPosition: 8\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AxDbAdminPwd\nPassword that is obtained from LCS\n\n```yaml\nType: String\nParameter Sets: ImportOnlyTier2\nAliases:\n\nRequired: False\nPosition: 9\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n```yaml\nType: String\nParameter Sets: ImportTier2\nAliases:\n\nRequired: True\nPosition: 9\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AxRuntimeUserPwd\nPassword that is obtained from LCS\n\n```yaml\nType: String\nParameter Sets: ImportOnlyTier2\nAliases:\n\nRequired: False\nPosition: 10\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n```yaml\nType: String\nParameter Sets: ImportTier2\nAliases:\n\nRequired: True\nPosition: 10\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AxMrRuntimeUserPwd\nPassword that is obtained from LCS\n\n```yaml\nType: String\nParameter Sets: ImportOnlyTier2\nAliases:\n\nRequired: False\nPosition: 11\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n```yaml\nType: String\nParameter Sets: ImportTier2\nAliases:\n\nRequired: True\nPosition: 11\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AxRetailRuntimeUserPwd\nPassword that is obtained from LCS\n\n```yaml\nType: String\nParameter Sets: ImportOnlyTier2\nAliases:\n\nRequired: False\nPosition: 12\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n```yaml\nType: String\nParameter Sets: ImportTier2\nAliases:\n\nRequired: True\nPosition: 12\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AxRetailDataSyncUserPwd\nPassword that is obtained from LCS\n\n```yaml\nType: String\nParameter Sets: ImportOnlyTier2\nAliases:\n\nRequired: False\nPosition: 13\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n```yaml\nType: String\nParameter Sets: ImportTier2\nAliases:\n\nRequired: True\nPosition: 13\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AxDbReadonlyUserPwd\nPassword that is obtained from LCS\n\n```yaml\nType: String\nParameter Sets: ImportOnlyTier2\nAliases:\n\nRequired: False\nPosition: 14\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n```yaml\nType: String\nParameter Sets: ImportTier2\nAliases:\n\nRequired: True\nPosition: 14\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -CustomSqlFile\nPath to the sql script file that you want the cmdlet to execute against your data after it has been imported\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ModelFile\nPath to the model file that you want the SqlPackage.exe to use instead the one being part of the bacpac file\n\nThis is used to override SQL Server options, like collation and etc\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DiagnosticFile\nPath to where you want the import to output a diagnostics file to assist you in troubleshooting the import\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ImportOnly\nSwitch to instruct the cmdlet to only import the bacpac into the new database\n\nThe cmdlet will create a new database and import the content of the bacpac file into this\n\nNothing else will be executed\n\n```yaml\nType: SwitchParameter\nParameter Sets: ImportTier1\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n```yaml\nType: SwitchParameter\nParameter Sets: ImportOnlyTier2\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MaxParallelism\nSets SqlPackage.exe's degree of parallelism for concurrent operations running against a database\n\nThe default value is 8\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: 8\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nThe path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: Named\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ImportBacpac\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Properties\nString array of properties to be used by SQLPackage.exe\nSee https://learn.microsoft.com/en-us/sql/tools/sqlpackage/sqlpackage-import#properties-specific-to-the-import-action for more information.\nNote that some properties are already set by the cmdlet, and cannot be overridden.\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Database, Bacpac, Tier1, Tier2, Golden Config, Config, Configuration\n\nAuthor: Rasmus Andersen (@ITRasmus)\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Import-D365Dacpac.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Import-D365Dacpac\n\n## SYNOPSIS\nImport dacpac file to a database\n\n## SYNTAX\n\n```\nImport-D365Dacpac [-Path] <String> [[-ModelFile] <String>] [[-PublishFile] <String>]\n [[-DiagnosticFile] <String>] [[-MaxParallelism] <Int32>] [[-DatabaseServer] <String>]\n [[-DatabaseName] <String>] [[-SqlUser] <String>] [[-SqlPwd] <String>] [[-LogPath] <String>]\n [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nImport a dacpac file into a database, using the publish feature of SqlPackage.exe\n\nIf the database doesn't exists, it will be created\n\nIf the database exists, the publish process from the dacpac file will make sure to align the different tables inside the database\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nImport-D365Dacpac -Path \"c:\\Temp\\AxDB.dacpac\" -ModelFile \"c:\\Temp\\dbo.salestable.model.xml\"\n```\n\nThis will import the dacpac file and use the modified model file while doing so.\nIt will use the \"c:\\Temp\\AxDB.dacpac\" as the Path parameter.\nIt will use the \"c:\\Temp\\dbo.salestable.model.xml\" as the ModelFile parameter.\n\nThis is used to enable single table restore / publish.\n\n### EXAMPLE 2\n```\nImport-D365Dacpac -Path \"c:\\Temp\\AxDB.dacpac\" -ModelFile \"c:\\Temp\\dbo.salestable.model.xml\" -DiagnosticFile \"C:\\temp\\ImportLog.txt\" -MaxParallelism 32\n```\n\nThis will import the dacpac file and use the modified model file while doing so.\nIt will use the \"c:\\Temp\\AxDB.dacpac\" as the Path parameter.\nIt will use the \"c:\\Temp\\dbo.salestable.model.xml\" as the ModelFile parameter.\nIt will use the \"C:\\temp\\ImportLog.txt\" as the DiagnosticFile parameter, where the diagnostic file will be stored.\n\nIt will use 32 connections against the database server while importing the bacpac file.\n\nThis is used to enable single table restore / publish.\n\n### EXAMPLE 3\n```\nImport-D365Dacpac -Path \"c:\\Temp\\AxDB.dacpac\" -PublishFile \"c:\\Temp\\publish.xml\"\n```\n\nThis will import the dacpac file and use the Publish file which contains advanced configuration instructions for SqlPackage.exe.\nIt will use the \"c:\\Temp\\AxDB.dacpac\" as the Path parameter.\nIt will use the \"c:\\Temp\\publish.xml\" as the PublishFile parameter, which contains advanced configuration instructions for SqlPackage.exe.\n\nThis is used to enable full restore / publish, but to avoid some of the common pitfalls.\n\n## PARAMETERS\n\n### -Path\nPath to the dacpac file that you want to import\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File, Dacpac\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ModelFile\nPath to the model file that you want the SqlPackage.exe to use instead the one being part of the dacpac file\n\nThis is used to override SQL Server options, like collation and etc\n\nThis is also used to support single table import / restore from a dacpac file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PublishFile\nPath to the publish / profile file that contains extended parameters for the SqlPackage.exe assembly\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: ProfileFile\n\nRequired: False\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DiagnosticFile\nPath to where you want the import to output a diagnostics file to assist you in troubleshooting the import\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MaxParallelism\nSets SqlPackage.exe's degree of parallelism for concurrent operations running against a database\n\nThe default value is 8\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: 8\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 8\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 9\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nThe path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 10\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ImportDacpac\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Database, Dacpac, Tier1, Tier2, Golden Config, Config, Configuration\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Import-D365ExternalUser.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Import-D365ExternalUser\n\n## SYNOPSIS\nImport an user from an external Azure Active Directory (AAD)\n\n## SYNTAX\n\n```\nImport-D365ExternalUser [-Id] <String> [-Name] <String> [-Email] <String> [[-Enabled] <Int32>]\n [[-Company] <String>] [[-Language] <String>] [[-DatabaseServer] <String>] [[-DatabaseName] <String>]\n [[-SqlUser] <String>] [[-SqlPwd] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nImports an user from an AAD that is NOT the same as the AAD tenant that the D365FO environment is running under\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nImport-D365ExternalUser -Id \"John\" -Name \"John Doe\" -Email \"John@contoso.com\"\n```\n\nThis will import an user from an external Azure Active Directory.\nThe new user will get the system wide Id \"John\".\nThe name of the new user will be \"John Doe\".\nThe e-mail address / sign-in e-mail address will be registered as \"John@contoso.com\".\n\n## PARAMETERS\n\n### -Id\nThe internal Id that the user must be imported with\n\nThe Id has to unique across the entire user base\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Name\nThe display name of the user inside the D365FO environment\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Email\nThe email address of the user that you want to import\n\nThis is also the sign-in user name / e-mail address to gain access to the system\n\nIf the external AAD tenant has multiple custom domain names, you have to use the domain that they have configured as default\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Enabled\nShould the imported user be enabled or not?\n\nDefault value is 1, which equals true / yes\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: 1\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Company\nDefault company that should be configured for the user, for when they sign-in to the D365 environment\n\nDefault value is \"DAT\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: DAT\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Language\nLanguage that should be configured for the user, for when they sign-in to the D365 environment\n\nDefault value is \"en-US\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: En-us\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 8\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 9\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 10\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: User, Users, Security, Configuration, Permission, AAD, Azure Active Directory\n\nAuthor: Anderson Joyle (@AndersonJoyle)\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Import-D365Model.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Import-D365Model\n\n## SYNOPSIS\nImport a model into Dynamics 365 for Finance & Operations\n\n## SYNTAX\n\n```\nImport-D365Model [-Path] <String> [[-BinDir] <String>] [[-MetaDataDir] <String>] [-Replace] [-LogPath <String>]\n [-ShowOriginalProgress] [-OutputCommandOnly] [<CommonParameters>]\n```\n\n## DESCRIPTION\nImport a model into a Dynamics 365 for Finance & Operations environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nImport-D365Model -Path c:\\temp\\d365fo.tools\\CustomModel.axmodel\n```\n\nThis will import the \"c:\\temp\\d365fo.tools\\CustomModel.axmodel\" model into the PackagesLocalDirectory location.\n\n### EXAMPLE 2\n```\nImport-D365Model -Path c:\\temp\\d365fo.tools\\CustomModel.axmodel -Replace\n```\n\nThis will import the \"c:\\temp\\d365fo.tools\\CustomModel.axmodel\" model into the PackagesLocalDirectory location.\nIf the model already exists it will replace it.\n\n## PARAMETERS\n\n### -Path\nPath to the axmodel file that you want to import\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the AOS service PackagesLocalDirectory\\bin\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: \"$Script:PackageDirectory\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetaDataDir\nThe path to the meta data directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: \"$Script:MetaDataDir\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Replace\nInstruct the cmdlet to replace an already existing model\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nThe path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: Named\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModelUtilImport\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: ModelUtil, Axmodel, Model, Import, Replace, Source Control, Vsts, Azure DevOps\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Import-D365RsatSelfServiceCertificates.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Import-D365RsatSelfServiceCertificates\n\n## SYNOPSIS\nImport certificates for RSAT\n\n## SYNTAX\n\n```\nImport-D365RsatSelfServiceCertificates [-Path] <String> [-Password] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\nImport the certificates for RSAT into the correct stores and display the thumbprint\n\nWhen working with self-service environments you need to download a zip file from LCS.\nThe zip file needs to be unblocked and then extracted into a folder, with only the .cer and the .pxf files inside\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nImport-D365RsatSelfServiceCertificates -Path \"C:\\Temp\\UAT\" -Password \"123456789\"\n```\n\nThis will import the .cer and .pxf files into the correct store, bases on the files located in \"C:\\Temp\\UAT\".\nAfter import it will display the thumbprint for both certificates.\n\nSample output:\n\\[23:43:05\\]\\[Import-D365RsatSelfServiceCertificates\\] Pfx Thumbprint:  B4D6921321434235463463414312343253523A05\n\\[23:43:05\\]\\[Import-D365RsatSelfServiceCertificates\\] Cert Thumbprint: B4D6921321434235463463414312343253523A05\n\n## PARAMETERS\n\n### -Path\nPath to the folder where the .cer and .pxf files are located\n\nThe files needs to be extracted from the zip archive\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Password\nPassword for the .pxf file\n\nWorking with self-service environments, the password will be displayed during the download of the zip archive\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Initialize-D365RsatCertificate.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Initialize-D365RsatCertificate\n\n## SYNOPSIS\nCreate and configure test automation certificate\n\n## SYNTAX\n\n```\nInitialize-D365RsatCertificate [-CertificateFileName <String>] [-PrivateKeyFileName <String>]\n [-Password <SecureString>] [-CertificateOnly] [-KeepCertificateFile] [-OutputPath <String>]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nCreates a new self signed certificate for automated testing and reconfigures the AOS Windows Identity Foundation configuration to trust the certificate\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInitialize-D365RsatCertificate\n```\n\nThis will generate a certificate for issuer 127.0.0.1 and install it in the trusted root certificates and modify the wif.config of the AOS to include the thumbprint and trust the certificate.\n\n### EXAMPLE 2\n```\nInitialize-D365RsatCertificate -CertificateOnly\n```\n\nThis will generate a certificate for issuer 127.0.0.1 and install it in the trusted root certificates.\nNo actions will be taken regarding modifying the AOS wif.config file.\n\nUse this when installing RSAT on a machine different from the AOS where RSAT is pointing to.\n\n### EXAMPLE 3\n```\nInitialize-D365RsatCertificate -CertificateOnly -KeepCertificateFile\n```\n\nThis will generate a certificate for issuer 127.0.0.1 and install it in the trusted root certificates.\nNo actions will be taken regarding modifying the AOS wif.config file.\nThe pfx will be copied into the default \"c:\\temp\\d365fo.tools\" folder after creation.\n\nUse this when installing RSAT on a machine different from the AOS where RSAT is pointing to.\n\nThe pfx file enables you to import the same certificate across your entire network, instead of creating one per machine.\n\n## PARAMETERS\n\n### -CertificateFileName\nFilename to be used when exporting the cer file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: (Join-Path $env:TEMP \"TestAuthCert.cer\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PrivateKeyFileName\nFilename to be used when exporting the pfx file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: (Join-Path $env:TEMP \"TestAuthCert.pfx\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Password\nThe password that you want to use to protect your certificate with\n\nThe default value is: \"Password1\"\n\n```yaml\nType: SecureString\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: (ConvertTo-SecureString -String \"Password1\" -Force -AsPlainText)\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -CertificateOnly\nSwitch specifying if only the certificate needs to be created\n\nIf specified, then only the certificate is created and the thumbprint is not added to the wif.config on the AOS side\nIf not specified (default) then the certificate is created and installed and the corresponding thumbprint is added to the wif.config on the local machine\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -KeepCertificateFile\nInstruct the cmdlet to copy the certificate file from the working directory into the desired location specified with OutputPath parameter\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputPath\nPath to where you want the certificate file exported to, when using the KeepCertificateFile parameter switch\n\nDefault value is: \"c:\\temp\\d365fo.tools\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Automated Test, Test, Regression, Certificate, Thumbprint\n\nAuthor: Kenny Saelen (@kennysaelen)\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Install-D365SupportingSoftware.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Install-D365SupportingSoftware\n\n## SYNOPSIS\nInstall software supporting F&O development\n\n## SYNTAX\n\n```\nInstall-D365SupportingSoftware [-Name] <String[]> [-Force] [<CommonParameters>]\n```\n\n## DESCRIPTION\nInstalls software commonly used when doing Dynamics 365 Finance and Operations development\n\nCommon ones: fiddler, postman, microsoft-edge, winmerge, notepadplusplus.install, azurepowershell, azure-cli, insomnia-rest-api-client, git.install\n\nFull list of software: https://community.chocolatey.org/packages\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInstall-D365SupportingSoftware -Name vscode\n```\n\nThis will install VSCode on the system.\n\n### EXAMPLE 2\n```\nInstall-D365SupportingSoftware -Name \"vscode\",\"fiddler\"\n```\n\nThis will install VSCode and fiddler on the system.\n\n### EXAMPLE 3\n```\nInstall-D365SupportingSoftware -Name vscode -Force\n```\n\nThis will install VSCode on the system, forcing it to be (re)installed.\n\n## PARAMETERS\n\n### -Name\nThe name of the software to install\n\nSupport a list of softwares that you want to have installed on the system\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases: SoftwareName\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nInstruct the cmdlet to install the latest version of the software, regardless if it is already present on the system\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Dag Calafell (@dodiggitydag)\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365AzCopyTransfer.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365AzCopyTransfer\n\n## SYNOPSIS\nTransfer a file using AzCopy\n\n## SYNTAX\n\n```\nInvoke-D365AzCopyTransfer [-SourceUri] <String> [-DestinationUri] <String> [[-FileName] <String>]\n [-DeleteOnTransferComplete] [[-LogPath] <String>] [-ShowOriginalProgress] [-OutputCommandOnly] [-Force]\n [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nTransfer a file using the AzCopy tool\n\nYou can upload a local file to an Azure Storage Blob Container\n\nYou can download a file located in an Azure Storage Blob Container to a local folder\n\nYou can transfer a file located in an Azure Storage Blob Container to another Azure Storage Blob Container, across regions and subscriptions, if you have SAS tokens/keys as part of your uri\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365AzCopyTransfer -SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\" -DestinationUri \"c:\\temp\\d365fo.tools\\GOLDER.bacpac\"\n```\n\nThis will transfer a file from an Azure Storage Blob Container to a local folder/file on the machine.\nThe file that will be transfered/downloaded is SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\".\nThe file will be transfered/downloaded to DestinationUri \"c:\\temp\\d365fo.tools\\GOLDER.bacpac\".\n\nIf there exists a file already, the file will NOT be overwritten.\n\n### EXAMPLE 2\n```\nInvoke-D365AzCopyTransfer -SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\" -DestinationUri \"c:\\temp\\d365fo.tools\\GOLDER.bacpac\" -Force\n```\n\nThis will transfer a file from an Azure Storage Blob Container to a local folder/file on the machine.\nThe file that will be transfered/downloaded is SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\".\nThe file will be transfered/downloaded to DestinationUri \"c:\\temp\\d365fo.tools\\GOLDER.bacpac\".\nIf there exists a file already, the file will  be overwritten, because Force has been supplied.\n\n### EXAMPLE 3\n```\nInvoke-D365AzCopyTransfer -SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\" -DestinationUri \"https://456.blob.core.windows.net/targetcontainer/filename?sv=2015-12-11&sr=...\"\n```\n\nThis will transfer a file from an Azure Storage Blob Container to another Azure Storage Blob Container.\nThe file that will be transfered/downloaded is SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\".\nThe file will be transfered/downloaded to DestinationUri \"https://456.blob.core.windows.net/targetcontainer/filename?sv=2015-12-11&sr=...\".\n\nFor this to work, you need to make sure both SourceUri and DestinationUri has an valid SAS token/key included.\n\nIf there exists a file already, the file will NOT be overwritten.\n\n### EXAMPLE 4\n```\nInvoke-D365AzCopyTransfer -SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\" -DestinationUri \"c:\\temp\\d365fo.tools\\GOLDER.bacpac\" -DeleteOnTransferComplete\n```\n\nThis will transfer a file from an Azure Storage Blob Container to a local folder/file on the machine.\nThe file that will be transfered/downloaded is SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\".\nThe file will be transfered/downloaded to DestinationUri \"c:\\temp\\d365fo.tools\\GOLDER.bacpac\".\n\nAfter the file has been transfered to your local \"c:\\temp\\d365fo.tools\\GOLDER.bacpac\", it will be deleted from the SourceUri \"https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...\".\n\n### EXAMPLE 5\n```\n$DestinationParms = Get-D365AzureStorageUrl -OutputAsHashtable\n```\n\nPS C:\\\\\\> $BlobFileDetails = Get-D365LcsDatabaseBackups -Latest | Invoke-D365AzCopyTransfer @DestinationParms\nPS C:\\\\\\> $BlobFileDetails | Invoke-D365AzCopyTransfer -DestinationUri \"C:\\Temp\" -DeleteOnTransferComplete\n\nThis will transfer the lastest backup file from LCS Asset Library to your local \"C:\\Temp\".\nIt will get a destination Url, for it to transfer the backup file between the LCS storage account and your own.\nThe newly transfered file, that lives in your own storage account, will then be downloaded to your local \"c:\\Temp\".\n\nAfter the file has been downloaded to your local \"C:\\Temp\", it will be deleted from your own storage account.\n\n## PARAMETERS\n\n### -SourceUri\nSource file uri that you want to transfer\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: FileLocation, SourceUrl\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -DestinationUri\nDestination file uri that you want to transfer the file to\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: DestinationFile\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FileName\nYou might only pass a blob container or folder name in the DestinationUri parameter and want to give the transfered file another name than the original file name\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -DeleteOnTransferComplete\nInstruct the cmdlet to delete the source file when done transfering\n\nDefault is $false which will leave the source file\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nThe path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 4\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\AzCopy\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nInstruct the cmdlet to overwrite already existing file\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Azure, Azure Storage, Config, Configuration, Token, Blob, File, Files, Latest, Bacpac, Container, LCS, Asset, Library\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThe cmdlet supports piping and can be used in advanced scenarios.\nSee more on github and the wiki pages.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365AzureDevOpsNugetPush.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365AzureDevOpsNugetPush\n\n## SYNOPSIS\nPush a package / nuget to Azure DevOps\n\n## SYNTAX\n\n```\nInvoke-D365AzureDevOpsNugetPush [[-Path] <String>] [[-Source] <String>] [[-LogPath] <String>]\n [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nPush a package / nuget to an Azure DevOps feed\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365AzureDevOpsNugetPush -Path \"c:\\temp\\d365fo.tools\\microsoft.dynamics.ax.application.devalm.buildxpp.10.0.605.10014.nupkg\" -Source \"Contoso\"\n```\n\nThis will push the package / nuget to the Azure DevOps feed.\nThe file that will be pushed / uploaded is identified by the Path \"c:\\temp\\d365fo.tools\\microsoft.dynamics.ax.application.devalm.buildxpp.10.0.605.10014.nupkg\".\nThe request will be going to the Azure DevOps instance that is registered with the Source (Name) \"Contoso\" via the nuget.exe tool.\n\n## PARAMETERS\n\n### -Path\nPath to the package / nuget that you want to push to the Azure DevOps feed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: PackagePath\n\nRequired: False\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Source\nThe logical name for the nuget source / connection that you want to use while pushing the package / nuget\n\nThis requires you to register the nuget source, by hand, using the nuget.exe tool directly\n\nBase command to use:\n.\\nuget sources add -Name \"D365FO\" -Source \"https://pkgs.dev.azure.com/Contoso/DynamicsFnO/_packaging/D365Packages/NuGet/v3/index.json\" -username \"alice@contoso.dk\" -password \"uVWw43FLzaWk9H2EDguXMVYD3DaWj3aHBL6bfZkc21cmkwoK8X78\"\n\nPlease note that the password is in fact a personal access token and NOT your real password\n\nThe value specified for Name in the nuget sources command, is the value to supply for Source for this cmdlet\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: NugetSource, Destination\n\nRequired: False\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nThe path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 3\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\Nuget\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365AzureStorageDownload.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365AzureStorageDownload\n\n## SYNOPSIS\nDownload a file to Azure\n\n## SYNTAX\n\n### Default (Default)\n```\nInvoke-D365AzureStorageDownload [-AccountId <String>] [-AccessToken <String>] [-SAS <String>]\n [-Container <String>] -FileName <String> [-Path <String>] [-Force] [-EnableException] [<CommonParameters>]\n```\n\n### Latest\n```\nInvoke-D365AzureStorageDownload [-AccountId <String>] [-AccessToken <String>] [-SAS <String>]\n [-Container <String>] [-Path <String>] [-Latest] [-Force] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nDownload any file to an Azure Storage Account\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365AzureStorageDownload -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Container \"backupfiles\" -FileName \"OriginalUAT.bacpac\" -Path \"c:\\temp\"\n```\n\nWill download the \"OriginalUAT.bacpac\" file from the storage account and save it to \"c:\\temp\\OriginalUAT.bacpac\"\n\n### EXAMPLE 2\n```\nInvoke-D365AzureStorageDownload -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Container \"backupfiles\" -Path \"c:\\temp\" -Latest\n```\n\nWill download the file with the latest modified datetime from the storage account and save it to \"c:\\temp\\\".\nThe complete path to the file will returned as output from the cmdlet.\n\n### EXAMPLE 3\n```\n$AzureParams = Get-D365ActiveAzureStorageConfig\n```\n\nPS C:\\\\\\> Invoke-D365AzureStorageDownload @AzureParams -Path \"c:\\temp\" -Latest\n\nThis will get the current Azure Storage Account configuration details\nand use them as parameters to download the latest file from an Azure Storage Account\n\nWill download the file with the latest modified datetime from the storage account and save it to \"c:\\temp\\\".\nThe complete path to the file will returned as output from the cmdlet.\n\n### EXAMPLE 4\n```\nInvoke-D365AzureStorageDownload -Latest\n```\n\nThis will use the default parameter values that are based on the configuration stored inside \"Get-D365ActiveAzureStorageConfig\".\nWill download the file with the latest modified datetime from the storage account and save it to \"c:\\temp\\d365fo.tools\".\n\n### EXAMPLE 5\n```\nInvoke-D365AzureStorageDownload -AccountId \"miscfiles\" -SAS \"sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" -Container \"backupfiles\" -Path \"c:\\temp\" -Latest\n```\n\nWill download the file with the latest modified datetime from the storage account and save it to \"c:\\temp\\\".\nA SAS key is used to gain access to the container and downloading the file from it.\nThe complete path to the file will returned as output from the cmdlet.\n\n## PARAMETERS\n\n### -AccountId\nStorage Account Name / Storage Account Id where you want to fetch the file from\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:AzureStorageAccountId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AccessToken\nThe token that has the needed permissions for the download action\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:AzureStorageAccessToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SAS\nThe SAS key that you have created for the storage account or blob container\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:AzureStorageSAS\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Container\nName of the blob container inside the storage account you where the file is\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Blobname, Blob\n\nRequired: False\nPosition: Named\nDefault value: $Script:AzureStorageContainer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FileName\nName of the file that you want to download\n\n```yaml\nType: String\nParameter Sets: Default\nAliases: Name\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Path\nPath to the folder / location you want to save the file\n\nThe default path is \"c:\\temp\\d365fo.tools\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Latest\nInstruct the cmdlet to download the latest file from Azure regardless of name\n\n```yaml\nType: SwitchParameter\nParameter Sets: Latest\nAliases: GetLatest\n\nRequired: True\nPosition: 5\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nInstruct the cmdlet to overwrite the local file if it already exists\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Azure, Azure Storage, Config, Configuration, Token, Blob, File, Files, Latest, Bacpac, Container\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThe cmdlet supports piping and can be used in advanced scenarios.\nSee more on github and the wiki pages.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365AzureStorageUpload.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365AzureStorageUpload\n\n## SYNOPSIS\nUpload a file to Azure\n\n## SYNTAX\n\n### Default (Default)\n```\nInvoke-D365AzureStorageUpload [-AccountId <String>] [-AccessToken <String>] [-SAS <String>]\n [-Container <String>] -Filepath <String> [-ContentType <String>] [-Force] [-DeleteOnUpload] [-EnableException]\n [<CommonParameters>]\n```\n\n### Pipeline\n```\nInvoke-D365AzureStorageUpload [-AccountId <String>] [-AccessToken <String>] [-SAS <String>]\n [-Container <String>] -Filepath <String> [-ContentType <String>] [-Force] [-DeleteOnUpload] [-EnableException]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nUpload any file to an Azure Storage Account\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365AzureStorageUpload -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Container \"backupfiles\" -Filepath \"c:\\temp\\bacpac\\UAT_20180701.bacpac\" -DeleteOnUpload\n```\n\nThis will upload the \"c:\\temp\\bacpac\\UAT_20180701.bacpac\" up to the \"backupfiles\" container, inside the \"miscfiles\" Azure Storage Account that is access with the \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" token.\nAfter upload the local file will be deleted.\n\n### EXAMPLE 2\n```\n$AzureParams = Get-D365ActiveAzureStorageConfig\n```\n\nPS C:\\\\\\> New-D365Bacpac | Invoke-D365AzureStorageUpload @AzureParams\n\nThis will get the current Azure Storage Account configuration details and use them as parameters to upload the file to an Azure Storage Account.\n\n### EXAMPLE 3\n```\nNew-D365Bacpac | Invoke-D365AzureStorageUpload\n```\n\nThis will generate a new bacpac file using the \"New-D365Bacpac\" cmdlet.\nThe file will be uploaded to an Azure Storage Account using the \"Invoke-D365AzureStorageUpload\" cmdlet.\nThis will use the default parameter values that are based on the configuration stored inside \"Get-D365ActiveAzureStorageConfig\" for the \"Invoke-D365AzureStorageUpload\" cmdlet.\n\n### EXAMPLE 4\n```\nInvoke-D365AzureStorageUpload -AccountId \"miscfiles\" -SAS \"sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk\" -Container \"backupfiles\" -Filepath \"c:\\temp\\bacpac\\UAT_20180701.bacpac\" -DeleteOnUpload\n```\n\nThis will upload the \"c:\\temp\\bacpac\\UAT_20180701.bacpac\" up to the \"backupfiles\" container, inside the \"miscfiles\" Azure Storage Account.\nA SAS key is used to gain access to the container and uploading the file to it.\n\n## PARAMETERS\n\n### -AccountId\nStorage Account Name / Storage Account Id where you want to store the file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:AzureStorageAccountId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AccessToken\nThe token that has the needed permissions for the upload action\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:AzureStorageAccessToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SAS\nThe SAS key that you have created for the storage account or blob container\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:AzureStorageSAS\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Container\nName of the blob container inside the storage account you want to store the file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Blobname, Blob\n\nRequired: False\nPosition: Named\nDefault value: $Script:AzureStorageContainer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Filepath\nPath to the file you want to upload\n\n```yaml\nType: String\nParameter Sets: Default\nAliases: Path, File\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByValue)\nAccept wildcard characters: False\n```\n\n```yaml\nType: String\nParameter Sets: Pipeline\nAliases: Path, File\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByValue)\nAccept wildcard characters: False\n```\n\n### -ContentType\nMedia type of the file that is going to be uploaded\n\nThe value will be used for the blob property \"Content Type\".\nIf the parameter is left empty, the commandlet will try to automatically determined the value based on the file's extension.\nIf the parameter is left empty and the value cannot be automatically be determined, Azure storage will automatically assign \"application/octet-stream\" as the content type.\nValid media type values can be found here: https://www.iana.org/assignments/media-types/media-types.xhtml\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nInstruct the cmdlet to overwrite the file in the container if it already exists\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DeleteOnUpload\nSwitch to tell the cmdlet if you want the local file to be deleted after the upload completes\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Azure, Azure Storage, Config, Configuration, Token, Blob, File, Files, Bacpac, Container\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThe cmdlet supports piping and can be used in advanced scenarios.\nSee more on github and the wiki pages.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365BestPractice.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365BestPractice\n\n## SYNOPSIS\nRun the Best Practice\n\n## SYNTAX\n\n```\nInvoke-D365BestPractice [-Module] <String> [-Model] <String> [[-BinDir] <String>] [[-MetaDataDir] <String>]\n [-PackagesRoot] [[-LogPath] <String>] [-ShowOriginalProgress] [-RunFixers] [-OutputCommandOnly]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nRun the Best Practice checks against modules and models\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365BestPractice -module \"ApplicationSuite\" -model \"MyOverLayerModel\"\n```\n\nThis will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module.\nThe default output will be silenced.\nThe XML log file will be written to \"c:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.MyOverLayerModel.xppbp.xml\".\nThe log file will be written to \"c:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.MyOverLayerModel.xppbp.log\".\n\n### EXAMPLE 2\n```\nInvoke-D365BestPractice -module \"ApplicationSuite\" -model \"MyOverLayerModel\" -PackagesRoot\n```\n\nThis will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module.\nWe use the binary metadata to look for the module and model.\nThe default output will be silenced.\nThe XML log file will be written to \"c:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.MyOverLayerModel.xppbp.xml\".\nThe log file will be written to \"c:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.MyOverLayerModel.xppbp.log\".\n\n### EXAMPLE 3\n```\nInvoke-D365BestPractice -module \"ApplicationSuite\" -model \"MyOverLayerModel\" -ShowOriginalProgress\n```\n\nThis will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module.\nThe output from the best practice check process will be written to the console / host.\nThe XML log file will be written to \"c:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.MyOverLayerModel.xppbp.xml\".\nThe log file will be written to \"c:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.MyOverLayerModel.xppbp.log\".\n\n### EXAMPLE 4\n```\nInvoke-D365BestPractice -module \"ApplicationSuite\" -model \"MyOverLayerModel\" -RunFixers\n```\n\nThis will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module.\nThe default output will be silenced.\nThe XML log file will be written to \"c:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.MyOverLayerModel.xppbp.xml\".\nThe log file will be written to \"c:\\temp\\d365fo.tools\\ApplicationSuite\\Dynamics.AX.MyOverLayerModel.xppbp.log\".\nInstructs the xppbp tool to run the fixers for all identified warnings.\n\n## PARAMETERS\n\n### -Module\nName of the Module to analyse\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: ModuleName\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Model\nName of the Model to analyse\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: ModelName\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the AOS service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: \"$Script:PackageDirectory\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetaDataDir\nThe path to the meta data directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: \"$Script:MetaDataDir\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackagesRoot\nInstructs the cmdlet to use binary metadata\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nPath where you want to store the log outputs generated from the best practice analyser\n\nAlso used as the path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 5\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\BestPractice\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RunFixers\nInstructs the cmdlet to invoke the fixers for the identified warnings\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### [PsCustomObject]\n## NOTES\nTags: Best Practice, BP, BPs, Module, Model, Quality\n\nAuthor: Gert Van Der Heyden (@gertvdheyden)\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365CompilerResultAnalyzer.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365CompilerResultAnalyzer\n\n## SYNOPSIS\nAnalyze the compiler output log\n\n## SYNTAX\n\n```\nInvoke-D365CompilerResultAnalyzer [-Path] <String> [[-OutputPath] <String>] [-SkipWarnings] [-SkipTasks]\n [[-PackageDirectory] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nAnalyze the compiler output log and generate an excel file contain worksheets per type: Errors, Warnings, Tasks\n\nIt could be a Visual Studio compiler log or it could be a Invoke-D365ModuleCompile log you want analyzed\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365CompilerResultAnalyzer -Path \"c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log\"\n```\n\nThis will analyse all compiler output log files generated from Visual Studio.\nIt will use the default path for the OutputPath parameter.\n\nIt will build error and error summary worksheets.\nIt will build warning and warning summary worksheets.\nIt will build task and task summary worksheets.\n\nA result set example:\n\nFile                                                            Filename\n----                                                            --------\nc:\\temp\\d365fo.tools\\Custom-CompilerResults.xlsx                Custom-CompilerResults.xlsx\n\n### EXAMPLE 2\n```\nInvoke-D365CompilerResultAnalyzer -Path \"c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log\" -SkipWarnings\n```\n\nThis will analyse all compiler output log files generated from Visual Studio.\nIt will use the default path for the OutputPath parameter.\n\nIt will build error and error summary worksheets.\nIt will build task and task summary worksheets.\n\nA result set example:\n\nFile                                                            Filename\n----                                                            --------\nc:\\temp\\d365fo.tools\\Custom-CompilerResults.xlsx                Custom-CompilerResults.xlsx\n\n### EXAMPLE 3\n```\nInvoke-D365CompilerResultAnalyzer -Path \"c:\\temp\\d365fo.tools\\Custom\\Dynamics.AX.Custom.xppc.log\" -SkipTasks\n```\n\nThis will analyse all compiler output log files generated from Visual Studio.\nIt will use the default path for the OutputPath parameter.\n\nIt will build error and error summary worksheets.\nIt will build warning and warning summary worksheets.\n\nA result set example:\n\nFile                                                            Filename\n----                                                            --------\nc:\\temp\\d365fo.tools\\Custom-CompilerResults.xlsx                Custom-CompilerResults.xlsx\n\n## PARAMETERS\n\n### -Path\nPath to the compiler log file that you want to work against\n\nA BuildModelResult.log or a Dynamics.AX.*.xppc.log file will both work\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogFile\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### -OutputPath\nPath where you want the excel file (xlsx-file) saved to\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SkipWarnings\nInstructs the cmdlet to skip warnings while analyzing the compiler output log file\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SkipTasks\nInstructs the cmdlet to skip tasks while analyzing the compiler output log file\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nDefault path is the same as the AOS service \"PackagesLocalDirectory\" directory\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Compiler, Build, Errors, Warnings, Tasks\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThis cmdlet is inspired by the work of \"Vilmos Kintera\" (twitter: @DAXRunBase)\n\nAll credits goes to him for showing how to extract these information\n\nHis blog can be found here:\nhttps://www.daxrunbase.com/blog/\n\nThe specific blog post that we based this cmdlet on can be found here:\nhttps://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/\n\nThe github repository containing the original scrips can be found here:\nhttps://github.com/DAXRunBase/PowerShell-and-Azure\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365DBSync.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365DbSync\n\n## SYNOPSIS\nInvoke the synchronization process used in Visual Studio\n\n## SYNTAX\n\n```\nInvoke-D365DbSync [[-BinDirTools] <String>] [[-MetadataDir] <String>] [[-SyncMode] <String>]\n [[-Verbosity] <String>] [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>]\n [[-SqlPwd] <String>] [[-LogPath] <String>] [-ShowOriginalProgress] [-OutputCommandOnly] [<CommonParameters>]\n```\n\n## DESCRIPTION\nUses the sync.exe (engine) to synchronize the database for the environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365DBSync\n```\n\nThis will invoke the sync engine and have it work against the database.\n\n### EXAMPLE 2\n```\nInvoke-D365DBSync -Verbose\n```\n\nThis will invoke the sync engine and have it work against the database.\nIt will output the same level of details that Visual Studio would normally do.\n\n## PARAMETERS\n\n### -BinDirTools\nPath to where the tools on the machine can be found\n\nDefault value is normally the AOS Service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:BinDirTools\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetadataDir\nPath to where the tools on the machine can be found\n\nDefault value is normally the AOS Service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SyncMode\nThe sync mode the sync engine will use\n\nDefault value is: \"FullAll\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: FullAll\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Verbosity\nParameter used to instruct the level of verbosity the sync engine has to report back\n\nDefault value is: \"Normal\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: Normal\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 8\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nThe path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 9\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\DbSync\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Database, Sync, SyncDB, Synchronization, Servicing\n\nAuthor: Rasmus Andersen (@ITRasmus)\nAuthor: Mötz Jensen (@Splaxi)\n\nWhen running the 'FullAll' (default) the command requires an elevated console / Run As Administrator.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365DBSyncPartial.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365DbSyncPartial\n\n## SYNOPSIS\nInvoke the synchronization process used in Visual Studio\n\n## SYNTAX\n\n```\nInvoke-D365DbSyncPartial [[-SyncList] <String[]>] [[-SyncExtensionsList] <String[]>] [[-SyncMode] <String>]\n [[-Verbosity] <String>] [[-BinDirTools] <String>] [[-MetadataDir] <String>] [[-DatabaseServer] <String>]\n [[-DatabaseName] <String>] [[-SqlUser] <String>] [[-SqlPwd] <String>] [[-LogPath] <String>]\n [-ShowOriginalProgress] [-OutputCommandOnly] [<CommonParameters>]\n```\n\n## DESCRIPTION\nUses the sync.exe (engine) to synchronize the database for the environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365DBSyncPartial -SyncList \"CustCustomerEntity\",\"SalesTable\"\n```\n\nThis will invoke the sync engine and have it work against the database.\nIt will run with the default value \"PartialList\" as the SyncMode.\nIt will run the sync process against \"CustCustomerEntity\" and \"SalesTable\"\n\n### EXAMPLE 2\n```\nInvoke-D365DBSyncPartial -SyncList \"CustCustomerEntity\",\"SalesTable\" -Verbose\n```\n\nThis will invoke the sync engine and have it work against the database.\nIt will run with the default value \"PartialList\" as the SyncMode.\nIt will run the sync process against \"CustCustomerEntity\" and \"SalesTable\"\n\nIt will output the same level of details that Visual Studio would normally do.\n\n### EXAMPLE 3\n```\nInvoke-D365DBSyncPartial -SyncList \"CustCustomerEntity\",\"SalesTable\" -SyncExtensionsList \"CaseLog.Extension\",\"CategoryTable.Extension\" -Verbose\n```\n\nThis will invoke the sync engine and have it work against the database.\nIt will run with the default value \"PartialList\" as the SyncMode.\nIt will run the sync process against \"CustCustomerEntity\", \"SalesTable\", \"CaseLog.Extension\" and \"CategoryTable.Extension\"\n\nIt will output the same level of details that Visual Studio would normally do.\n\n## PARAMETERS\n\n### -SyncList\nThe list of objects that you want to pass on to the database synchronoziation engine\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SyncExtensionsList\nThe list of extension objects that you want to pass on to the database synchronoziation engine\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SyncMode\nThe sync mode the sync engine will use\n\nDefault value is: \"PartialList\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: PartialList\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Verbosity\nParameter used to instruct the level of verbosity the sync engine has to report back\n\nDefault value is: \"Normal\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: Normal\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDirTools\nPath to where the tools on the machine can be found\n\nDefault value is normally the AOS Service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:BinDirTools\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetadataDir\nPath to where the tools on the machine can be found\n\nDefault value is normally the AOS Service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 8\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 9\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 10\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nThe path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 11\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\DbSync\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Database, Sync, SyncDB, Synchronization, Servicing\n\nAuthor: Mötz Jensen (@Splaxi)\n\nAuthor: Jasper Callens - Cegeka\n\nInspired by:\nhttps://axdynamx.blogspot.com/2017/10/how-to-synchronize-manually-database.html\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365DataFlush.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365DataFlush\n\n## SYNOPSIS\nInvoke the one of the data flush classes\n\n## SYNTAX\n\n```\nInvoke-D365DataFlush [[-Url] <String>] [-Class <String[]>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nInvoke one of the runnable classes that is clearing cache, data or something else\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365DataFlush\n```\n\nThis will make a call against the default URL for the machine and\nhave it execute the SysFlushAOD class.\n\n### EXAMPLE 2\n```\nInvoke-D365DataFlush -Class SysFlushData,SysFlushAod\n```\n\nThis will make a call against the default URL for the machine and\nhave it execute the SysFlushData and SysFlushAod classes.\n\n## PARAMETERS\n\n### -Url\nURL to the Dynamics 365 instance you want to clear the AOD cache on\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Class\nThe class that you want to execute.\n\nDefault value is \"SysFlushAod\"\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: SysFlushAod\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Flush, Url, Servicing\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365DbSyncModule.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365DbSyncModule\n\n## SYNOPSIS\nSynchronize all sync base and extension elements based on a modulename\n\n## SYNTAX\n\n```\nInvoke-D365DbSyncModule [-Module] <String[]> [[-Verbosity] <String>] [[-BinDirTools] <String>]\n [[-MetadataDir] <String>] [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>]\n [[-SqlPwd] <String>] [[-LogPath] <String>] [-ShowOriginalProgress] [-OutputCommandOnly] [<CommonParameters>]\n```\n\n## DESCRIPTION\nRetrieve the list of installed packages / modules where the name fits the ModelName parameter.\n\nIt will run loop over the list and start the sync process against all tables, views, data entities, table-extensions,\nview-extensions and data entities-extensions of every iterated model\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365DbSyncModule -Module \"MyModel1\"\n```\n\nIt will start the sync process against all tables, views, data entities, table-extensions, view-extensions and data entities-extensions of MyModel1.\n\n### EXAMPLE 2\n```\nInvoke-D365DbSyncModule -Module \"MyModel1\",\"MyModel2\"\n```\n\nIt will run loop over the list and start the sync process against all tables, views, data entities, table-extensions, view-extensions and data entities-extensions of every iterated model.\n\n### EXAMPLE 3\n```\nGet-D365Module -Name \"MyModel*\" | Invoke-D365DbSyncModule\n```\n\nRetrieve the list of installed packages / modules where the name fits the search \"MyModel*\".\n\nThe result is:\nMyModel1\nMyModel2\n\nIt will run loop over the list and start the sync process against all tables, views, data entities, table-extensions, view-extensions and data entities-extensions of every iterated model.\n\n## PARAMETERS\n\n### -Module\nName of the model you want to sync tables and table extensions\n\nSupports an array of module names\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases: ModuleName\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### -Verbosity\nParameter used to instruct the level of verbosity the sync engine has to report back\n\nDefault value is: \"Normal\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: Normal\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDirTools\nPath to where the tools on the machine can be found\n\nDefault value is normally the AOS Service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:BinDirTools\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetadataDir\nPath to where the tools on the machine can be found\n\nDefault value is normally the AOS Service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 8\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nThe path where the log file will be saved\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 9\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\DbSync\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Database, Sync, SyncDB, Synchronization, Servicing\n\nAuthor: Jasper Callens - Cegeka\n\nAuthor: Caleb Blanchard (@daxcaleb)\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365GenerateReportAggregateDataEntity.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365GenerateReportAggregateDataEntity\n\n## SYNOPSIS\nGenerate Report for Aggregate Data Entity\n\n## SYNTAX\n\n```\nInvoke-D365GenerateReportAggregateDataEntity [[-OutputPath] <String>] [[-BinDir] <String>]\n [[-PackageDirectory] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nTraverse the Dynamics 365 Finance & Operations code repository for all Aggregate Data Entities and generate a metadata report\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365GenerateReportAggregateDataEntity\n```\n\nThis will generate a report.\nIt will contain all the metadata and save it into a xlsx (Excel) file.\nIt will saved the file to \"c:\\temp\\d365fo.tools\\\"\n\n## PARAMETERS\n\n### -OutputPath\nPath to where you want the report file to be saved\n\nThe default value is: \"c:\\temp\\d365fo.tools\\\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Metadata, Report, Documentation\nAuthor: Mötz Jensen (@Splaxi)\n\nMIT License\n\nCopyright (c) Microsoft Corporation.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365GenerateReportAggregateMeasure.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365GenerateReportAggregateMeasure\n\n## SYNOPSIS\nGenerate Report for Aggregate Measure\n\n## SYNTAX\n\n```\nInvoke-D365GenerateReportAggregateMeasure [[-OutputPath] <String>] [[-BinDir] <String>]\n [[-PackageDirectory] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nTraverse the Dynamics 365 Finance & Operations code repository for all Aggregate Measures and generate a metadata report\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365GenerateReportAggregateMeasure\n```\n\nThis will generate a report.\nIt will contain all the metadata and save it into a xlsx (Excel) file.\nIt will saved the file to \"c:\\temp\\d365fo.tools\\\"\n\n## PARAMETERS\n\n### -OutputPath\nPath to where you want the report file to be saved\n\nThe default value is: \"c:\\temp\\d365fo.tools\\\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Metadata, Report, Documentation\nAuthor: Mötz Jensen (@Splaxi)\n\nMIT License\n\nCopyright (c) Microsoft Corporation.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365GenerateReportConfigKey.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365GenerateReportConfigKey\n\n## SYNOPSIS\nGenerate Report for Config Key\n\n## SYNTAX\n\n```\nInvoke-D365GenerateReportConfigKey [[-OutputPath] <String>] [[-BinDir] <String>] [[-PackageDirectory] <String>]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nTraverse the Dynamics 365 Finance & Operations code repository for all Config Keys and generate a metadata report\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365GenerateReportConfigKey\n```\n\nThis will generate a report.\nIt will contain all the metadata and save it into a xlsx (Excel) file.\nIt will saved the file to \"c:\\temp\\d365fo.tools\\\"\n\n## PARAMETERS\n\n### -OutputPath\nPath to where you want the report file to be saved\n\nThe default value is: \"c:\\temp\\d365fo.tools\\\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Metadata, Report, Documentation\nAuthor: Mötz Jensen (@Splaxi)\n\nMIT License\n\nCopyright (c) Microsoft Corporation.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365GenerateReportConfigKeyGroup.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365GenerateReportConfigKeyGroup\n\n## SYNOPSIS\nGenerate Report for Config Key Group\n\n## SYNTAX\n\n```\nInvoke-D365GenerateReportConfigKeyGroup [[-OutputPath] <String>] [[-BinDir] <String>]\n [[-PackageDirectory] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nTraverse the Dynamics 365 Finance & Operations code repository for all Config Key Groups and generate a metadata report\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365GenerateReportConfigKeyGroup\n```\n\nThis will generate a report.\nIt will contain all the metadata and save it into a xlsx (Excel) file.\nIt will saved the file to \"c:\\temp\\d365fo.tools\\\"\n\n## PARAMETERS\n\n### -OutputPath\nPath to where you want the report file to be saved\n\nThe default value is: \"c:\\temp\\d365fo.tools\\\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Metadata, Report, Documentation\nAuthor: Mötz Jensen (@Splaxi)\n\nMIT License\n\nCopyright (c) Microsoft Corporation.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365GenerateReportDataEntity.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365GenerateReportDataEntity\n\n## SYNOPSIS\nGenerate Report for Data Entity\n\n## SYNTAX\n\n```\nInvoke-D365GenerateReportDataEntity [[-OutputPath] <String>] [[-BinDir] <String>]\n [[-PackageDirectory] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nTraverse the Dynamics 365 Finance & Operations code repository for all Data Entities and generate a metadata report\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365GenerateReportDataEntity\n```\n\nThis will generate a report.\nIt will contain all the metadata and save it into a xlsx (Excel) file.\nIt will saved the file to \"c:\\temp\\d365fo.tools\\\"\n\n## PARAMETERS\n\n### -OutputPath\nPath to where you want the report file to be saved\n\nThe default value is: \"c:\\temp\\d365fo.tools\\\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Metadata, Report, Documentation\nAuthor: Mötz Jensen (@Splaxi)\n\nMIT License\n\nCopyright (c) Microsoft Corporation.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365GenerateReportDataEntityField.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365GenerateReportDataEntityField\n\n## SYNOPSIS\nGenerate Report for Data Entity with fields\n\n## SYNTAX\n\n```\nInvoke-D365GenerateReportDataEntityField [[-OutputPath] <String>] [[-BinDir] <String>]\n [[-PackageDirectory] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nTraverse the Dynamics 365 Finance & Operations code repository for all Data Entities with their fields and generate a metadata report\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365GenerateReportDataEntityField\n```\n\nThis will generate a report.\nIt will contain all the metadata and save it into a xlsx (Excel) file.\nIt will saved the file to \"c:\\temp\\d365fo.tools\\\"\n\n## PARAMETERS\n\n### -OutputPath\nPath to where you want the report file to be saved\n\nThe default value is: \"c:\\temp\\d365fo.tools\\\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Metadata, Report, Documentation\nAuthor: Mötz Jensen (@Splaxi)\n\nMIT License\n\nCopyright (c) Microsoft Corporation.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365GenerateReportKpi.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365GenerateReportKpi\n\n## SYNOPSIS\nGenerate Report for KPI\n\n## SYNTAX\n\n```\nInvoke-D365GenerateReportKpi [[-OutputPath] <String>] [[-BinDir] <String>] [[-PackageDirectory] <String>]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nTraverse the Dynamics 365 Finance & Operations code repository for all KPIs and generate a metadata report\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365GenerateReportKpi\n```\n\nThis will generate a report.\nIt will contain all the metadata and save it into a xlsx (Excel) file.\nIt will saved the file to \"c:\\temp\\d365fo.tools\\\"\n\n## PARAMETERS\n\n### -OutputPath\nPath to where you want the report file to be saved\n\nThe default value is: \"c:\\temp\\d365fo.tools\\\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Metadata, Report, Documentation\nAuthor: Mötz Jensen (@Splaxi)\n\nMIT License\n\nCopyright (c) Microsoft Corporation.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365GenerateReportLicenseCode.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365GenerateReportLicenseCode\n\n## SYNOPSIS\nGenerate Report for License Code\n\n## SYNTAX\n\n```\nInvoke-D365GenerateReportLicenseCode [[-OutputPath] <String>] [[-BinDir] <String>]\n [[-PackageDirectory] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nTraverse the Dynamics 365 Finance & Operations code repository for all License Codes and generate a metadata report\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365GenerateReportLicenseCode\n```\n\nThis will generate a report.\nIt will contain all the metadata and save it into a xlsx (Excel) file.\nIt will saved the file to \"c:\\temp\\d365fo.tools\\\"\n\n## PARAMETERS\n\n### -OutputPath\nPath to where you want the report file to be saved\n\nThe default value is: \"c:\\temp\\d365fo.tools\\\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Metadata, Report, Documentation\nAuthor: Mötz Jensen (@Splaxi)\n\nMIT License\n\nCopyright (c) Microsoft Corporation.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365GenerateReportMenuItem.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365GenerateReportMenuItem\n\n## SYNOPSIS\nGenerate Report for Menu Item\n\n## SYNTAX\n\n```\nInvoke-D365GenerateReportMenuItem [[-OutputPath] <String>] [[-BinDir] <String>] [[-PackageDirectory] <String>]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nTraverse the Dynamics 365 Finance & Operations code repository for all types of Menu Items and generate a metadata report\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365GenerateReportMenuItem\n```\n\nThis will generate a report.\nIt will contain all the metadata and save it into a xlsx (Excel) file.\nIt will saved the file to \"c:\\temp\\d365fo.tools\\\"\n\n## PARAMETERS\n\n### -OutputPath\nPath to where you want the report file to be saved\n\nThe default value is: \"c:\\temp\\d365fo.tools\\\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Metadata, Report, Documentation\nAuthor: Mötz Jensen (@Splaxi)\n\nMIT License\n\nCopyright (c) Microsoft Corporation.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365GenerateReportSsrs.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365GenerateReportSsrs\n\n## SYNOPSIS\nGenerate Report for SSRS Report\n\n## SYNTAX\n\n```\nInvoke-D365GenerateReportSsrs [[-OutputPath] <String>] [[-BinDir] <String>] [[-PackageDirectory] <String>]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nTraverse the Dynamics 365 Finance & Operations code repository for all SSRS Reports and generate a metadata report\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365GenerateReportSsrs\n```\n\nThis will generate a report.\nIt will contain all the metadata and save it into a xlsx (Excel) file.\nIt will saved the file to \"c:\\temp\\d365fo.tools\\\"\n\n## PARAMETERS\n\n### -OutputPath\nPath to where you want the report file to be saved\n\nThe default value is: \"c:\\temp\\d365fo.tools\\\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Metadata, Report, Documentation\nAuthor: Mötz Jensen (@Splaxi)\n\nMIT License\n\nCopyright (c) Microsoft Corporation.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365GenerateReportTable.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365GenerateReportTable\n\n## SYNOPSIS\nGenerate Report for Table\n\n## SYNTAX\n\n```\nInvoke-D365GenerateReportTable [[-OutputPath] <String>] [[-BinDir] <String>] [[-PackageDirectory] <String>]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nTraverse the Dynamics 365 Finance & Operations code repository for all Tables and generate a metadata report\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365GenerateReportTable\n```\n\nThis will generate a report.\nIt will contain all the metadata and save it into a xlsx (Excel) file.\nIt will saved the file to \"c:\\temp\\d365fo.tools\\\"\n\n## PARAMETERS\n\n### -OutputPath\nPath to where you want the report file to be saved\n\nThe default value is: \"c:\\temp\\d365fo.tools\\\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Metadata, Report, Documentation\nAuthor: Mötz Jensen (@Splaxi)\n\nMIT License\n\nCopyright (c) Microsoft Corporation.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365GenerateReportWorkflowType.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365GenerateReportWorkflowType\n\n## SYNOPSIS\nGenerate Report for Workflow Type\n\n## SYNTAX\n\n```\nInvoke-D365GenerateReportWorkflowType [[-OutputPath] <String>] [[-BinDir] <String>]\n [[-PackageDirectory] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nTraverse the Dynamics 365 Finance & Operations code repository for all Workflow Types and generate a metadata report\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365GenerateReportWorkflowType\n```\n\nThis will generate a report.\nIt will contain all the metadata and save it into a xlsx (Excel) file.\nIt will saved the file to \"c:\\temp\\d365fo.tools\\\"\n\n## PARAMETERS\n\n### -OutputPath\nPath to where you want the report file to be saved\n\nThe default value is: \"c:\\temp\\d365fo.tools\\\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Metadata, Report, Documentation\nAuthor: Mötz Jensen (@Splaxi)\n\nMIT License\n\nCopyright (c) Microsoft Corporation.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365GenerateReports.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365GenerateReports\n\n## SYNOPSIS\nGenerate Report for all related objects\n\n## SYNTAX\n\n```\nInvoke-D365GenerateReports [[-OutputPath] <String>] [[-BinDir] <String>] [[-PackageDirectory] <String>]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nTraverse the Dynamics 365 Finance & Operations code repository for all related objects and generate a metadata report for each\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365GenerateReports\n```\n\nThis will generate a report for each related object.\nIt will contain all the metadata and save it into a xlsx (Excel) file.\nIt will saved the file to \"c:\\temp\\d365fo.tools\\\"\n\n## PARAMETERS\n\n### -OutputPath\nPath to where you want the report file to be saved\n\nThe default value is: \"c:\\temp\\d365fo.tools\\\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nNormally it is located under the AOSService directory in \"PackagesLocalDirectory\"\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Metadata, Report, Documentation\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365InstallAzCopy.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365InstallAzCopy\n\n## SYNOPSIS\nDownload AzCopy.exe to your machine\n\n## SYNTAX\n\n```\nInvoke-D365InstallAzCopy [[-Url] <String>] [[-Path] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nDownload and extract the AzCopy.exe to your machine\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365InstallAzCopy -Path \"C:\\temp\\d365fo.tools\\AzCopy\\AzCopy.exe\"\n```\n\nThis will update the path for the AzCopy.exe in the modules configuration\n\n## PARAMETERS\n\n### -Url\nUrl/Uri to where the latest AzCopy download is located\n\nThe default value is for v10 as of writing\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: Https://aka.ms/downloadazcopy-v10-windows\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Path\nPath to where you want the AzCopy to be extracted to\n\nDefault value is: \"C:\\temp\\d365fo.tools\\AzCopy\\AzCopy.exe\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: C:\\temp\\d365fo.tools\\AzCopy\\AzCopy.exe\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365InstallLicense.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365InstallLicense\n\n## SYNOPSIS\nInstall a license for a 3.\nparty solution\n\n## SYNTAX\n\n```\nInvoke-D365InstallLicense [-Path] <String> [[-DatabaseServer] <String>] [[-DatabaseName] <String>]\n [[-SqlUser] <String>] [[-SqlPwd] <String>] [[-MetaDataDir] <String>] [[-BinDir] <String>]\n [[-LogPath] <String>] [-ShowOriginalProgress] [-OutputCommandOnly] [<CommonParameters>]\n```\n\n## DESCRIPTION\nInstall a license for a 3.\nparty solution using the builtin \"Microsoft.Dynamics.AX.Deployment.Setup.exe\" executable\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365InstallLicense -Path c:\\temp\\d365fo.tools\\license.txt\n```\n\nThis will use the default paths and start the Microsoft.Dynamics.AX.Deployment.Setup.exe with the needed parameters to import / install the license file.\n\n### EXAMPLE 2\n```\nInvoke-D365InstallLicense -Path c:\\temp\\d365fo.tools\\license.txt -ShowOriginalProgress\n```\n\nThis will use the default paths and start the Microsoft.Dynamics.AX.Deployment.Setup.exe with the needed parameters to import / install the license file.\nThe output from the installation process will be written to the console / host.\n\n## PARAMETERS\n\n### -Path\nPath to the license file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetaDataDir\nThe path to the meta data directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: \"$Script:MetaDataDir\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: \"$Script:BinDir\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nThe path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 8\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\InstallLicense\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: License, Install, ISV, 3.\nParty, Servicing\n\nAuthor: Mötz Jensen (@splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365InstallNuget.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365InstallNuget\n\n## SYNOPSIS\nDownload nuget.exe to your machine\n\n## SYNTAX\n\n```\nInvoke-D365InstallNuget [[-Path] <String>] [[-Url] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nDownload the nuget.exe to your machine\n\nBy default it will download the latest version\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365InstallNuget\n```\n\nThis will download the latest version of nuget.\nThe install path is identified by the default value: \"C:\\temp\\d365fo.tools\\nuget\\nuget.exe\".\n\n## PARAMETERS\n\n### -Path\nPath to where you want the nuget.exe to be downloaded to\n\nDefault value is: \"C:\\temp\\d365fo.tools\\nuget\\nuget.exe\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: C:\\temp\\d365fo.tools\\nuget\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Url\nUrl/Uri to where the latest nuget download is located\n\nThe default value is \"https://dist.nuget.org/win-x86-commandline/latest/nuget.exe\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: Https://dist.nuget.org/win-x86-commandline/latest/nuget.exe\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365InstallSqlPackage.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365InstallSqlPackage\n\n## SYNOPSIS\nDownload SqlPackage.exe to your machine\n\n## SYNTAX\n\n### ImportUrl (Default)\n```\nInvoke-D365InstallSqlPackage [-Path <String>] [-Url <String>] [<CommonParameters>]\n```\n\n### ImportLatest\n```\nInvoke-D365InstallSqlPackage [-Path <String>] [-Latest] [<CommonParameters>]\n```\n\n## DESCRIPTION\nDownload and extract SqlPackage.exe to your machine.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365InstallSqlPackage\n```\n\nThis will download and extract SqlPackage.exe.\nIt will use the default value for the Path parameter, for where to save the SqlPackage.exe.\nIt will update the path for the SqlPackage.exe in configuration.\n\n### EXAMPLE 2\n```\nInvoke-D365InstallSqlPackage -Path \"C:\\temp\\SqlPackage\"\n```\n\nThis will download and extract SqlPackage.exe.\nIt will save the SqlPackage.exe to \"C:\\temp\\SqlPackage\".\nIt will update the path for the SqlPackage.exe in configuration.\n\n### EXAMPLE 3\n```\nInvoke-D365InstallSqlPackage -Latest\n```\n\nThis will download and extract the latest SqlPackage.exe.\nIt will use https://aka.ms/sqlpackage-windows as the download URL.\nIt will update the path for the SqlPackage.exe in configuration.\n\n### EXAMPLE 4\n```\nInvoke-D365InstallSqlPackage -Url \"https://go.microsoft.com/fwlink/?linkid=3030303\"\n```\n\nThis will download and extract SqlPackage.exe.\nIt will rely on the Url parameter to base the download on.\nIt will use the \"https://go.microsoft.com/fwlink/?linkid=3030303\" as value for the Url parameter.\nIt will update the path for the SqlPackage.exe in configuration.\n\n## PARAMETERS\n\n### -Path\nPath to where you want the SqlPackage to be extracted to\n\nDefault value is: \"C:\\temp\\d365fo.tools\\SqlPackage\\SqlPackage.exe\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: C:\\temp\\d365fo.tools\\SqlPackage\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Latest\nOverrides the Url parameter and uses the latest download URL provided by the evergreen link https://aka.ms/sqlpackage-windows\n\n```yaml\nType: SwitchParameter\nParameter Sets: ImportLatest\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Url\nUrl/Uri to where the SqlPackage download is located\n\nThe default value is for version 162.2.111.2 as of writing.\n\nFurther discussion can be found here: https://github.com/d365collaborative/d365fo.tools/discussions/816\n\n```yaml\nType: String\nParameter Sets: ImportUrl\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: Https://go.microsoft.com/fwlink/?linkid=2261576\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\nAuthor: Florian Hopfner (@FH-Inway)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365LcsApiRefreshToken.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365LcsApiRefreshToken\n\n## SYNOPSIS\nRefresh the token for lcs communication\n\n## SYNTAX\n\n### Object\n```\nInvoke-D365LcsApiRefreshToken -ClientId <String> [-InputObject <PSObject>] [-EnableException]\n [<CommonParameters>]\n```\n\n### Simple\n```\nInvoke-D365LcsApiRefreshToken -ClientId <String> -RefreshToken <String> [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nInvoke the refresh logic that refreshes the token object based on the ClientId and RefreshToken\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365LcsApiRefreshToken -ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" -RefreshToken \"Tsdljfasfe2j32324\"\n```\n\nThis will refresh an OAuth 2.0 access token, and obtain a (new) valid OAuth 2.0 access token from Azure Active Directory.\nThe ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" is used in the OAuth 2.0 \"Refresh Token\" Grant Flow to authenticate.\nThe RefreshToken \"Tsdljfasfe2j32324\" is used to prove to Azure Active Directoy that we are allowed to obtain a new valid Access Token.\n\n### EXAMPLE 2\n```\n$temp = Get-D365LcsApiToken -LcsApiUri \"https://lcsapi.eu.lcs.dynamics.com\" -ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" -Username \"serviceaccount@domain.com\" -Password \"TopSecretPassword\"\n```\n\nPS C:\\\\\\> $temp = Invoke-D365LcsApiRefreshToken -ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" -InputObject $temp\n\nThis will refresh an OAuth 2.0 access token, and obtain a (new) valid OAuth 2.0 access token from Azure Active Directory.\nThis will obtain a new token object from the Get-D365LcsApiToken cmdlet and store it in $temp.\nThen it will pass $temp to the Invoke-D365LcsApiRefreshToken along with the ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\".\nThe new token object will be save into $temp.\n\n### EXAMPLE 3\n```\nGet-D365LcsApiConfig | Invoke-D365LcsApiRefreshToken | Set-D365LcsApiConfig\n```\n\nThis will refresh an OAuth 2.0 access token, and obtain a (new) valid OAuth 2.0 access token from Azure Active Directory.\nThis will fetch the current LCS API details from Get-D365LcsApiConfig.\nThe output from Get-D365LcsApiConfig is piped directly to Invoke-D365LcsApiRefreshToken, which will fetch a new token object.\nThe new token object is piped directly into Set-D365LcsApiConfig, which will save the needed details into the configuration store.\n\n## PARAMETERS\n\n### -ClientId\nThe Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal\n\n```yaml\nType: String\nParameter Sets: Object\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n```yaml\nType: String\nParameter Sets: Simple\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RefreshToken\nThe Refresh Token that you want to use for the authentication process\n\n```yaml\nType: String\nParameter Sets: Simple\nAliases: Token, refresh_token\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -InputObject\nThe entire object that you received from the Get-D365LcsApiToken command, which contains the needed RefreshToken\n\n```yaml\nType: PSObject\nParameter Sets: Object\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: LCS, API, Token, BearerToken\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Get-D365LcsApiConfig]()\n\n[Get-D365LcsApiToken]()\n\n[Get-D365LcsAssetValidationStatus]()\n\n[Get-D365LcsDeploymentStatus]()\n\n[Invoke-D365LcsDeployment]()\n\n[Invoke-D365LcsUpload]()\n\n[Set-D365LcsApiConfig]()\n\n"
  },
  {
    "path": "docs/Invoke-D365LcsDatabaseExport.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365LcsDatabaseExport\n\n## SYNOPSIS\nStart a database export from an environment\n\n## SYNTAX\n\n```\nInvoke-D365LcsDatabaseExport [[-ProjectId] <Int32>] [[-BearerToken] <String>] [-SourceEnvironmentId] <String>\n [-BackupName] <String> [[-LcsApiUri] <String>] [-SkipInitialStatusFetch] [-FailOnErrorMessage]\n [[-RetryTimeout] <TimeSpan>] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nStart a database export from an environment from a LCS project\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365LcsDatabaseExport -ProjectId 123456789 -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -BackupName \"BackupViaApi\" -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n```\n\nThis will start the database export from the Source environment.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\nThe backup name is identified by the BackupName \"BackupViaApi\", which instructs the API to save the backup with that filename.\nThe request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\nThe http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n\n### EXAMPLE 2\n```\nInvoke-D365LcsDatabaseExport -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -BackupName \"BackupViaApi\"\n```\n\nThis will start the database export from the Source environment.\nThe source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\nThe backup name is identified by the BackupName \"BackupViaApi\", which instructs the API to save the backup with that filename.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 3\n```\n$databaseExport = Invoke-D365LcsDatabaseExport -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -BackupName \"BackupViaApi\" -SkipInitialStatusFetch\n```\n\nPS C:\\\\\\> $databaseExport | Get-D365LcsDatabaseOperationStatus -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e9\" -SleepInSeconds 60\n\nThis will start the database export from the Source environment.\nThe source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\nThe backup name is identified by the BackupName \"BackupViaApi\", which instructs the API to save the backup with that filename.\nIt will skip the first database operation status fetch and only output the details from starting the export.\n\nThe output from Invoke-D365LcsDatabaseExport is stored in the $databaseExport.\nThis will enable you to pass the $databaseExport variable to other cmdlets which should make things easier for you.\n\nWill pipe the $databaseExport variable to the Get-D365LcsDatabaseOperationStatus cmdlet and get the status from the database export job.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 4\n```\nInvoke-D365LcsDatabaseExport -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -BackupName \"BackupViaApi\" -SkipInitialStatusFetch\n```\n\nThis will start the database export from the Source environment.\nThe source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\nThe backup name is identified by the BackupName \"BackupViaApi\", which instructs the API to save the backup with that filename.\nIt will skip the first database operation status fetch and only output the details from starting the export.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 5\n```\nInvoke-D365LcsDatabaseExport -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -BackupName \"BackupViaApi\" -RetryTimeout \"00:01:00\"\n```\n\nThis will start the database export from the Source environment, and allow for the cmdlet to retry for no more than 1 minute.\nThe source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\nThe backup name is identified by the BackupName \"BackupViaApi\", which instructs the API to save the backup with that filename.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n## PARAMETERS\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:LcsApiProjectId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Token\n\nRequired: False\nPosition: 2\nDefault value: $Script:LcsApiBearerToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SourceEnvironmentId\nThe unique id of the environment that you want to use as the source for the database export\n\nThe Id can be located inside the LCS portal\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BackupName\nName of the backup file when it is being exported from the environment\n\nThe file shouldn't contain any extension at all, just the desired file name\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 4\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SkipInitialStatusFetch\nInstruct the cmdlet to skip the first fetch of the database refresh status\n\nUseful when you have a large script that handles this status validation and you don't want to spend time with this cmdlet\n\nDefault output from this cmdlet is 2 (two) different objects.\nThe first object is the response object for starting the export operation.\nThe second object is the response object from fetching the status of the export operation.\n\nSetting this parameter (activate it), will affect the number of output objects.\nIf you skip, only the first response object outputted.\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FailOnErrorMessage\nInstruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\nThis allows you to implement custom retry / error handling logic\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RetryTimeout\nThe retry timeout, before the cmdlet should quit retrying based on the 429 status code\n\nNeeds to be provided in the timspan notation:\n\"hh:mm:ss\"\n\nhh is the number of hours, numerical notation only\nmm is the number of minutes\nss is the numbers of seconds\n\nEach section of the timeout has to valid, e.g.\nhh can maximum be 23\nmm can maximum be 59\nss can maximum be 59\n\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n\n```yaml\nType: TimeSpan\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: 00:00:00\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nThe ActivityId property is a custom property that ISN'T part of the response from the LCS API.\nThe ActivityId is always the same as the OperationActivityId (original LCS property).\nThe EnvironmentId property is a custom property that ISN'T part of the response from the LCS API.\nThe EnvironmentId is always the same as the SourceEnvironmentId parameter you have supplied to this cmdlet.\n\nDefault output from this cmdlet is 2 (two) different objects.\nThe first object is the response object for starting the export operation.\nThe second object is the response object from fetching the status of the export operation.\n\nSetting the SkipInitialStatusFetch parameter (activate it), will affect the number of output objects.\nIf you skip, only the first response object outputted.\n\nRunning with the default (SkipInitialStatusFetch NOT being set), will instruct the cmdlet to call the Get-D365LcsDatabaseOperationStatus cmdlet.\nThis will output a second object, with other properties than the first object outputted.\n\nTags: Environment, Config, Configuration, LCS, Database backup, Api, Backup, Bacpac\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Get-D365LcsDatabaseOperationStatus]()\n\n[Get-D365LcsApiConfig]()\n\n[Get-D365LcsApiToken]()\n\n[Get-D365LcsAssetValidationStatus]()\n\n[Get-D365LcsDeploymentStatus]()\n\n[Invoke-D365LcsApiRefreshToken]()\n\n[Invoke-D365LcsUpload]()\n\n[Set-D365LcsApiConfig]()\n\n"
  },
  {
    "path": "docs/Invoke-D365LcsDatabaseRefresh.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365LcsDatabaseRefresh\n\n## SYNOPSIS\nStart a database refresh between 2 environments\n\n## SYNTAX\n\n```\nInvoke-D365LcsDatabaseRefresh [[-ProjectId] <Int32>] [[-BearerToken] <String>] [-SourceEnvironmentId] <String>\n [-TargetEnvironmentId] <String> [[-LcsApiUri] <String>] [-SkipInitialStatusFetch] [-FailOnErrorMessage]\n [[-RetryTimeout] <TimeSpan>] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nStart a database refresh between 2 environments from a LCS project\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365LcsDatabaseRefresh -ProjectId 123456789 -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n```\n\nThis will start the database refresh between the Source and Target environments.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\nThe target environment is identified by the TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\nThe request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\nThe http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n\n### EXAMPLE 2\n```\nInvoke-D365LcsDatabaseRefresh -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n```\n\nThis will start the database refresh between the Source and Target environments.\nThe source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\nThe target environment is identified by the TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 3\n```\n$databaseRefresh = Invoke-D365LcsDatabaseRefresh -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -SkipInitialStatusFetch\n```\n\nPS C:\\\\\\> $databaseRefresh | Get-D365LcsDatabaseOperationStatus -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e9\" -SleepInSeconds 60\n\nThis will start the database refresh between the Source and Target environments.\nThe source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\nThe target environment is identified by the TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\nIt will skip the first database refesh status fetch and only output the details from starting the refresh.\n\nThe output from Invoke-D365LcsDatabaseRefresh is stored in the $databaseRefresh.\nThis will enable you to pass the $databaseRefresh variable to other cmdlets which should make things easier for you.\n\nWill pipe the $databaseRefresh variable to the Get-D365LcsDatabaseOperationStatus cmdlet and get the status from the database refresh job.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 4\n```\nInvoke-D365LcsDatabaseRefresh -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -SkipInitialStatusFetch\n```\n\nThis will start the database refresh between the Source and Target environments.\nThe source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\nThe target environment is identified by the TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\nIt will skip the first database refesh status fetch and only output the details from starting the refresh.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 5\n```\nInvoke-D365LcsDatabaseRefresh -SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\" -TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -RetryTimeout \"00:01:00\"\n```\n\nThis will start the database refresh between the Source and Target environments, and allow for the cmdlet to retry for no more than 1 minute.\nThe source environment is identified by the SourceEnvironmentId \"958ae597-f089-4811-abbd-c1190917eaae\", which can be obtained in the LCS portal.\nThe target environment is identified by the TargetEnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n## PARAMETERS\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:LcsApiProjectId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Token\n\nRequired: False\nPosition: 2\nDefault value: $Script:LcsApiBearerToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SourceEnvironmentId\nThe unique id of the environment that you want to use as the source for the database refresh\n\nThe Id can be located inside the LCS portal\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -TargetEnvironmentId\nThe unique id of the environment that you want to use as the target for the database refresh\n\nThe Id can be located inside the LCS portal\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 4\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SkipInitialStatusFetch\nInstruct the cmdlet to skip the first fetch of the database refresh status\n\nUseful when you have a large script that handles this status validation and you don't want to spend time with this cmdlet\n\nDefault output from this cmdlet is 2 (two) different objects.\nThe first object is the response object for starting the refresh operation.\nThe second object is the response object from fetching the status of the refresh operation.\n\nSetting this parameter (activate it), will affect the number of output objects.\nIf you skip, only the first response object outputted.\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FailOnErrorMessage\nInstruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\nThis allows you to implement custom retry / error handling logic\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RetryTimeout\nThe retry timeout, before the cmdlet should quit retrying based on the 429 status code\n\nNeeds to be provided in the timspan notation:\n\"hh:mm:ss\"\n\nhh is the number of hours, numerical notation only\nmm is the number of minutes\nss is the numbers of seconds\n\nEach section of the timeout has to valid, e.g.\nhh can maximum be 23\nmm can maximum be 59\nss can maximum be 59\n\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n\n```yaml\nType: TimeSpan\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: 00:00:00\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nThe ActivityId property is a custom property that ISN'T part of the response from the LCS API.\nThe ActivityId is always the same as the OperationActivityId (original LCS property).\nThe EnvironmentId property is a custom property that ISN'T part of the response from the LCS API.\nThe EnvironmentId is always the same as the SourceEnvironmentId parameter you have supplied to this cmdlet.\n\nDefault output from this cmdlet is 2 (two) different objects.\nThe first object is the response object for starting the refresh operation.\nThe second object is the response object from fetching the status of the refresh operation.\n\nSetting the SkipInitialStatusFetch parameter (activate it), will affect the number of output objects.\nIf you skip, only the first response object outputted.\n\nRunning with the default (SkipInitialStatusFetch NOT being set), will instruct the cmdlet to call the Get-D365LcsDatabaseOperationStatus cmdlet.\nThis will output a second object, with other properties than the first object outputted.\n\nTags: Environment, Config, Configuration, LCS, Database backup, Api, Backup, Restore, Refresh\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Get-D365LcsApiConfig]()\n\n[Get-D365LcsApiToken]()\n\n[Get-D365LcsAssetValidationStatus]()\n\n[Get-D365LcsDeploymentStatus]()\n\n[Invoke-D365LcsApiRefreshToken]()\n\n[Invoke-D365LcsUpload]()\n\n[Set-D365LcsApiConfig]()\n\n"
  },
  {
    "path": "docs/Invoke-D365LcsDeployment.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365LcsDeployment\n\n## SYNOPSIS\nStart the deployment of a deployable package\n\n## SYNTAX\n\n### VM (Default)\n```\nInvoke-D365LcsDeployment [-ProjectId <Int32>] -AssetId <String> -EnvironmentId <String> [-BearerToken <String>]\n [-LcsApiUri <String>] [-FailOnErrorMessage] [-RetryTimeout <TimeSpan>] [-EnableException] [<CommonParameters>]\n```\n\n### Self-Service\n```\nInvoke-D365LcsDeployment [-ProjectId <Int32>] -AssetId <String> -EnvironmentId <String> -UpdateName <String>\n [-BearerToken <String>] [-LcsApiUri <String>] [-FailOnErrorMessage] [-RetryTimeout <TimeSpan>]\n [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nDeploy a deployable package from the Asset Library from a LCS project using the API provided by Microsoft\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365LcsDeployment -ProjectId 123456789 -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -BearerToken \"Bearer JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n```\n\nThis will start the deployment of the file located in the Asset Library.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\nThe request will authenticate with the BearerToken \"Bearer JldjfafLJdfjlfsalfd...\".\nThe http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n\n### EXAMPLE 2\n```\nInvoke-D365LcsDeployment -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n```\n\nThis will start the deployment of the file located in the Asset Library.\nThe file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 3\n```\nInvoke-D365LcsDeployment -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -UpdateName \"Release_XYZ\"\n```\n\nThis will start the deployment of the file located in the Asset Library against a Self-Service environment.\nThe file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\nThe deployment is name \"Release_XYZ\" by setting the UpdateName parameter, which is mandatory when working against Self-Service environments.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 4\n```\nInvoke-D365LcsDeployment -AssetId \"958ae597-f089-4811-abbd-c1190917eaae\" -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -RetryTimeout \"00:01:00\"\n```\n\nThis will start the deployment of the file located in the Asset Library, and allow for the cmdlet to retry for no more than 1 minute.\nThe file is identified by the AssetId \"958ae597-f089-4811-abbd-c1190917eaae\", which is obtained either by earlier upload or simply looking in the LCS portal.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n## PARAMETERS\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:LcsApiProjectId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AssetId\nThe unique id of the asset / file that you are trying to deploy from LCS\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -EnvironmentId\nThe unique id of the environment that you want to work against\n\nThe Id can be located inside the LCS portal\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -UpdateName\nName of the update when you are working against Self-Service environments\n\n```yaml\nType: String\nParameter Sets: Self-Service\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Token\n\nRequired: False\nPosition: Named\nDefault value: $Script:LcsApiBearerToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FailOnErrorMessage\nInstruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\nThis allows you to implement custom retry / error handling logic\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RetryTimeout\nThe retry timeout, before the cmdlet should quit retrying based on the 429 status code\n\nNeeds to be provided in the timspan notation:\n\"hh:mm:ss\"\n\nhh is the number of hours, numerical notation only\nmm is the number of minutes\nss is the numbers of seconds\n\nEach section of the timeout has to valid, e.g.\nhh can maximum be 23\nmm can maximum be 59\nss can maximum be 59\n\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n\n```yaml\nType: TimeSpan\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: 00:00:00\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token, Deployment, Deploy\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Get-D365LcsApiConfig]()\n\n[Get-D365LcsApiToken]()\n\n[Get-D365LcsAssetValidationStatus]()\n\n[Get-D365LcsDeploymentStatus]()\n\n[Invoke-D365LcsApiRefreshToken]()\n\n[Invoke-D365LcsUpload]()\n\n[Set-D365LcsApiConfig]()\n\n"
  },
  {
    "path": "docs/Invoke-D365LcsEnvironmentStart.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365LcsEnvironmentStart\n\n## SYNOPSIS\nStart a specified environment through LCS.\n\n## SYNTAX\n\n```\nInvoke-D365LcsEnvironmentStart [[-ProjectId] <Int32>] [[-BearerToken] <String>] [-EnvironmentId] <String>\n [[-LcsApiUri] <String>] [-FailOnErrorMessage] [[-RetryTimeout] <TimeSpan>] [-EnableException]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nStart a specified IAAS environment that is Customer Managed through the LCS API.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365LcsEnvironmentStart -ProjectId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n```\n\nThis will trigger the environment start operation upon the given environment through the LCS API.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\nThe request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\nThe http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n\n### EXAMPLE 2\n```\nInvoke-D365LcsEnvironmentStart -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n```\n\nThis will trigger the environment start operation upon the given environment through the LCS API.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 3\n```\nInvoke-D365LcsEnvironmentStart -ProjectId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -RetryTimeout \"00:01:00\"\n```\n\nThis will trigger the environment start operation upon the given environment through the LCS API, and allow for the cmdlet to retry for no more than 1 minute.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n## PARAMETERS\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:LcsApiProjectId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Token\n\nRequired: False\nPosition: 2\nDefault value: $Script:LcsApiBearerToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnvironmentId\nThe unique id of the environment that you want to take action upon\n\nThe Id can be located inside the LCS portal\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FailOnErrorMessage\nInstruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\nThis allows you to implement custom retry / error handling logic\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RetryTimeout\nThe retry timeout, before the cmdlet should quit retrying based on the 429 status code\n\nNeeds to be provided in the timspan notation:\n\"hh:mm:ss\"\n\nhh is the number of hours, numerical notation only\nmm is the number of minutes\nss is the numbers of seconds\n\nEach section of the timeout has to valid, e.g.\nhh can maximum be 23\nmm can maximum be 59\nss can maximum be 59\n\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n\n```yaml\nType: TimeSpan\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: 00:00:00\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nOnly Customer Managed IAAS environments are supported with this API.\nMicrosoft Managed IAAS environments need to remain online to allow for Microsoft update operations and are not supported with this API.\nSelf-service environments do not have a stop functionality and will not work with this API.\n\nTags: Environment, Start, StartStop, Stop, LCS, Api\n\nAuthor: Mötz Jensen (@Splaxi), Billy Richardson (@richardsondev)\n\n## RELATED LINKS\n\n[Get-D365LcsApiConfig]()\n\n[Get-D365LcsApiToken]()\n\n[Invoke-D365LcsApiRefreshToken]()\n\n[Set-D365LcsApiConfig]()\n\n[Invoke-D365LcsEnvironmentStop]()\n\n"
  },
  {
    "path": "docs/Invoke-D365LcsEnvironmentStop.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365LcsEnvironmentStop\n\n## SYNOPSIS\nStop a specified environment through LCS.\n\n## SYNTAX\n\n```\nInvoke-D365LcsEnvironmentStop [[-ProjectId] <Int32>] [[-BearerToken] <String>] [-EnvironmentId] <String>\n [[-LcsApiUri] <String>] [-FailOnErrorMessage] [[-RetryTimeout] <TimeSpan>] [-EnableException]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nStop a specified IAAS environment that is Customer Managed through the LCS API.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365LcsEnvironmentStop -ProjectId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n```\n\nThis will trigger the environment stop operation upon the given environment through the LCS API.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\nThe request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\nThe http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n\n### EXAMPLE 2\n```\nInvoke-D365LcsEnvironmentStop -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\"\n```\n\nThis will trigger the environment stop operation upon the given environment through the LCS API.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 3\n```\nInvoke-D365LcsEnvironmentStop -ProjectId 123456789 -EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\" -RetryTimeout \"00:01:00\"\n```\n\nThis will trigger the environment stop operation upon the given environment through the LCS API, and allow for the cmdlet to retry for no more than 1 minute.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe environment is identified by the EnvironmentId \"13cc7700-c13b-4ea3-81cd-2d26fa72ec5e\", which can be obtained in the LCS portal.\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n## PARAMETERS\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:LcsApiProjectId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Token\n\nRequired: False\nPosition: 2\nDefault value: $Script:LcsApiBearerToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnvironmentId\nThe unique id of the environment that you want to take action upon\n\nThe Id can be located inside the LCS portal\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FailOnErrorMessage\nInstruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\nThis allows you to implement custom retry / error handling logic\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RetryTimeout\nThe retry timeout, before the cmdlet should quit retrying based on the 429 status code\n\nNeeds to be provided in the timspan notation:\n\"hh:mm:ss\"\n\nhh is the number of hours, numerical notation only\nmm is the number of minutes\nss is the numbers of seconds\n\nEach section of the timeout has to valid, e.g.\nhh can maximum be 23\nmm can maximum be 59\nss can maximum be 59\n\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n\n```yaml\nType: TimeSpan\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: 00:00:00\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nOnly Customer Managed IAAS environments are supported with this API.\nMicrosoft Managed IAAS environments need to remain online to allow for Microsoft update operations and are not supported with this API.\nSelf-service environments do not have a stop functionality and will not work with this API.\n\nTags: Environment, Stop, StartStop, Start, LCS, Api\n\nAuthor: Mötz Jensen (@Splaxi), Billy Richardson (@richardsondev)\n\n## RELATED LINKS\n\n[Get-D365LcsApiConfig]()\n\n[Get-D365LcsApiToken]()\n\n[Invoke-D365LcsApiRefreshToken]()\n\n[Set-D365LcsApiConfig]()\n\n[Invoke-D365LcsEnvironmentStart]()\n\n"
  },
  {
    "path": "docs/Invoke-D365LcsUpload.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365LcsUpload\n\n## SYNOPSIS\nUpload a file to a LCS project\n\n## SYNTAX\n\n```\nInvoke-D365LcsUpload [[-ProjectId] <Int32>] [[-BearerToken] <String>] [-FilePath] <String>\n [[-FileType] <LcsAssetFileType>] [[-Name] <String>] [[-Filename] <String>] [[-FileDescription] <String>]\n [[-LcsApiUri] <String>] [-FailOnErrorMessage] [[-RetryTimeout] <TimeSpan>] [-EnableException]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nUpload a file to a LCS project using the API provided by Microsoft\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365LcsUpload -ProjectId 123456789 -BearerToken \"Bearer JldjfafLJdfjlfsalfd...\" -FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\" -FileType \"SoftwareDeployablePackage\" -Name \"Release-2019-05-05\" -Filename \"Release-2019-05-05.zip\" -FileDescription \"Build based on sprint: SuperSprint-1\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n```\n\nThis will start the upload of a file to the Asset Library.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe file that will be uploaded is based on the FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\".\nThe file type \"Software Deployable Package\" determines where inside the Asset Library the file will end up.\nThe name inside the Asset Library is based on the Name \"Release-2019-05-05\".\nThe file name inside the Asset Library is based on the FileName \"Release-2019-05-05.zip\".\nThe description inside the Asset Library is based on the FileDescription \"Build based on sprint: SuperSprint-1\".\nThe request will authenticate with the BearerToken \"Bearer JldjfafLJdfjlfsalfd...\".\nThe http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n\n### EXAMPLE 2\n```\nInvoke-D365LcsUpload -FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\" -FileType \"SoftwareDeployablePackage\" -FileName \"Release-2019-05-05.zip\"\n```\n\nThis will start the upload of a file to the Asset Library.\nThe file that will be uploaded is based on the FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\".\nThe file type \"Software Deployable Package\" determines where inside the Asset Library the file will end up.\nThe file name inside the Asset Library is based on the FileName \"Release-2019-05-05.zip\".\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 3\n```\nInvoke-D365LcsUpload -FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\"\n```\n\nThis will start the upload of a file to the Asset Library.\nThe file that will be uploaded is based on the FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\".\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n### EXAMPLE 4\n```\nInvoke-D365LcsUpload -FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\" -RetryTimeout \"00:01:00\"\n```\n\nThis will start the upload of a file to the Asset Library through the LCS API, and allow for the cmdlet to retry for no more than 1 minute.\nThe file that will be uploaded is based on the FilePath \"C:\\temp\\d365fo.tools\\Release-2019-05-05.zip\".\n\nAll default values will come from the configuration available from Get-D365LcsApiConfig.\n\nThe default values can be configured using Set-D365LcsApiConfig.\n\n## PARAMETERS\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:LcsApiProjectId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Token\n\nRequired: False\nPosition: 2\nDefault value: $Script:LcsApiBearerToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FilePath\nPath to the file that you want to upload to the Asset Library on LCS\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FileType\nType of file you want to upload\n\nValid options:\n\"Model\"\n\"Process Data Package\"\n\"Software Deployable Package\"\n\"GER Configuration\"\n\"Data Package\"\n\"PowerBI Report Model\"\n\"E-Commerce Package\"\n\"NuGet Package\"\n\"Retail Self-Service Package\"\n\"Commerce Cloud Scale Unit Extension\"\n\nDefault value is \"Software Deployable Package\"\n\n```yaml\nType: LcsAssetFileType\nParameter Sets: (All)\nAliases:\nAccepted values: Model, ProcessDataPackage, SoftwareDeployablePackage, GERConfiguration, DataPackage, PowerBIReportModel, ECommercePackage, NuGetPackage, RetailSelfServicePackage, CommerceCloudScaleUnitExtension\n\nRequired: False\nPosition: 4\nDefault value: SoftwareDeployablePackage\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Name\nName to be assigned / shown on LCS\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Filename\nFilename to be assigned / shown on LCS\n\nOften will it require an extension for it to be accepted\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FileDescription\nDescription to be assigned / shown on LCS\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 8\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FailOnErrorMessage\nInstruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint\n\nUsed in combination with either Enable-D365Exception cmdlet, or the -EnableException directly on this cmdlet, it will throw an exception and break/stop execution of the script\nThis allows you to implement custom retry / error handling logic\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RetryTimeout\nThe retry timeout, before the cmdlet should quit retrying based on the 429 status code\n\nNeeds to be provided in the timspan notation:\n\"hh:mm:ss\"\n\nhh is the number of hours, numerical notation only\nmm is the number of minutes\nss is the numbers of seconds\n\nEach section of the timeout has to valid, e.g.\nhh can maximum be 23\nmm can maximum be 59\nss can maximum be 59\n\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n\n```yaml\nType: TimeSpan\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 9\nDefault value: 00:00:00\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Get-D365LcsApiConfig]()\n\n[Get-D365LcsApiToken]()\n\n[Get-D365LcsAssetValidationStatus]()\n\n[Get-D365LcsDeploymentStatus]()\n\n[Invoke-D365LcsApiRefreshToken]()\n\n[Invoke-D365LcsDeployment]()\n\n[Set-D365LcsApiConfig]()\n\n"
  },
  {
    "path": "docs/Invoke-D365ModuleCompile.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365ModuleCompile\n\n## SYNOPSIS\nCompile a package / module / model\n\n## SYNTAX\n\n```\nInvoke-D365ModuleCompile [-Module] <String> [[-OutputDir] <String>] [[-LogPath] <String>]\n [[-MetaDataDir] <String>] [[-ReferenceDir] <String>] [[-BinDir] <String>] [[-XRefSqlServer] <String>]\n [[-XRefDbName] <String>] [-XRefGeneration] [-XRefGenerationOnly] [-ShowOriginalProgress] [-OutputCommandOnly]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nCompile a package / module / model using the builtin \"xppc.exe\" executable to compile source code\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365ModuleCompile -Module MyModel\n```\n\nThis will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package.\nThe default output from the compile will be silenced.\n\nIf an error should occur, both the standard output and error output will be written to the console / host.\n\n### EXAMPLE 2\n```\nInvoke-D365ModuleCompile -Module MyModel -ShowOriginalProgress\n```\n\nThis will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package.\nThe output from the compile will be written to the console / host.\n\n### EXAMPLE 3\n```\nInvoke-D365ModuleCompile -Module MyModel -XRefGeneration\n```\n\nThis will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package.\nThe default output from the compile will be silenced.\nThe compiler will generate XRef metadata while compiling.\n\nIf an error should occur, both the standard output and error output will be written to the console / host.\n\n### EXAMPLE 4\n```\nInvoke-D365ModuleCompile -Module MyModel -XRefGenerationOnly\n```\n\nThis will use the default paths and start the xppc.exe with the needed parameters to only generate cross references for the MyModel package.\n\n### EXAMPLE 5\n```\nGet-D365Module -ExcludeBinaryModules -InDependencyOrder | Invoke-D365ModuleCompile -XRefGenerationOnly -ShowOriginalProgress\n```\n\nThis will update all cross references, keeping the assemblies and PDB files unmodified.\nThe output from the compile will be written to the console / host.\n\n## PARAMETERS\n\n### -Module\nThe package to compile\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: ModuleName\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -OutputDir\nThe path to the folder to save generated artifacts\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Output\n\nRequired: False\nPosition: 2\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nPath where you want to store the log outputs generated from the compiler\n\nAlso used as the path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 3\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModuleCompile\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetaDataDir\nThe path to the meta data directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ReferenceDir\nThe full path of a folder containing all assemblies referenced from X++ code\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:BinDirTools\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -XRefSqlServer\nThe name of the SQL server where the cross references database is located; the default is \"$env:COMPUTERNAME\"\nThis parameter is only used for XRefGenerationOnly\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: $env:COMPUTERNAME\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -XRefDbName\nThe name of the cross references database; the default is \"DYNAMICSXREFDB\"\nThis parameter is only used for XRefGenerationOnly\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 8\nDefault value: DYNAMICSXREFDB\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -XRefGeneration\nInstruct the cmdlet to enable the generation of XRef metadata while running the compile\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -XRefGenerationOnly\nInstruct the cmdlet to only generate XRef metadata while running the compile and not update the assemblies and PDB files\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### [PsCustomObject]\n## NOTES\nTags: Compile, Model, Servicing, X++\n\nAuthor: Ievgen Miroshnikov (@IevgenMir)\n\nAuthor: Mötz Jensen (@Splaxi)\n\nAuthor: Frank Hüther (@FrankHuether)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365ModuleFullCompile.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365ModuleFullCompile\n\n## SYNOPSIS\nCompile a package\n\n## SYNTAX\n\n```\nInvoke-D365ModuleFullCompile [-Module] <String> [[-OutputDir] <String>] [[-LogPath] <String>]\n [[-MetaDataDir] <String>] [[-ReferenceDir] <String>] [[-BinDir] <String>] [-ShowOriginalProgress]\n [-OutputCommandOnly] [<CommonParameters>]\n```\n\n## DESCRIPTION\nCompile a package using the builtin \"xppc.exe\" executable to compile source code, \"labelc.exe\" to compile label files and \"reportsc.exe\" to compile reports\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365ModuleFullCompile -Module MyModel\n```\n\nThis will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package.\nThe default output from all the different steps will be silenced.\n\n### EXAMPLE 2\n```\nInvoke-D365ModuleFullCompile -Module MyModel -ShowOriginalProgress\n```\n\nThis will use the default paths and start the xppc.exe with the needed parameters to copmile MyModel package.\nThe default output from the different steps will be written to the console / host.\n\n## PARAMETERS\n\n### -Module\nThe package to compile\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: ModuleName\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -OutputDir\nThe path to the folder to save assemblies\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Output\n\nRequired: False\nPosition: 2\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nPath where you want to store the log outputs generated from the compiler\n\nAlso used as the path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 3\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModuleCompile\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetaDataDir\nThe path to the meta data directory for the environment\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ReferenceDir\nThe full path of a folder containing all assemblies referenced from X++ code\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:BinDirTools\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### [PsCustomObject]\n## NOTES\nTags: Compile, Model, Servicing\n\nAuthor: Ievgen Miroshnikov (@IevgenMir)\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365ModuleLabelGeneration.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365ModuleLabelGeneration\n\n## SYNOPSIS\nGenerate labels for a package / module / model\n\n## SYNTAX\n\n```\nInvoke-D365ModuleLabelGeneration [-Module] <String> [[-OutputDir] <String>] [[-LogPath] <String>]\n [[-MetaDataDir] <String>] [[-ReferenceDir] <String>] [[-BinDir] <String>] [-ShowOriginalProgress]\n [-OutputCommandOnly] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGenerate labels for a package / module / model using the builtin \"labelc.exe\"\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365ModuleLabelGeneration -Module MyModel\n```\n\nThis will use the default paths and start the labelc.exe with the needed parameters to labels from the MyModel package.\nThe default output from the generation process will be silenced.\n\nIf an error should occur, both the standard output and error output will be written to the console / host.\n\n### EXAMPLE 2\n```\nInvoke-D365ModuleLabelGeneration -Module MyModel -ShowOriginalProgress\n```\n\nThis will use the default paths and start the labelc.exe with the needed parameters to labels from the MyModel package.\nThe output from the compile will be written to the console / host.\n\n## PARAMETERS\n\n### -Module\nName of the package that you want to work against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: ModuleName\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -OutputDir\nThe path to the folder to save generated artifacts\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Output\n\nRequired: False\nPosition: 2\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nPath where you want to store the log outputs generated from the compiler\n\nAlso used as the path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 3\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModuleCompile\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetaDataDir\nThe path to the meta data directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ReferenceDir\nThe full path of a folder containing all assemblies referenced from X++ code\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:BinDirTools\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### [PsCustomObject]\n## NOTES\nTags: Compile, Model, Servicing, Label, Labels\n\nAuthor: Ievgen Miroshnikov (@IevgenMir)\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365ModuleReportsCompile.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365ModuleReportsCompile\n\n## SYNOPSIS\nGenerate reports for a package / module / model\n\n## SYNTAX\n\n```\nInvoke-D365ModuleReportsCompile [-Module] <String> [[-OutputDir] <String>] [[-LogPath] <String>]\n [[-MetaDataDir] <String>] [[-ReferenceDir] <String>] [[-BinDir] <String>] [-ShowOriginalProgress]\n [-OutputCommandOnly] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGenerate reports for a package / module / model using the builtin \"ReportsC.exe\"\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365ModuleReportsCompile -Module MyModel\n```\n\nThis will use the default paths and start the ReportsC.exe with the needed parameters to compile the reports from the MyModel package.\nThe default output from the reports compile will be silenced.\n\nIf an error should occur, both the standard output and error output will be written to the console / host.\n\n### EXAMPLE 2\n```\nInvoke-D365ModuleReportsCompile -Module MyModel -ShowOriginalProgress\n```\n\nThis will use the default paths and start the ReportsC.exe with the needed parameters to compile the reports from the MyModel package.\nThe output from the compile will be written to the console / host.\n\n## PARAMETERS\n\n### -Module\nName of the package that you want to work against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: ModuleName\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -OutputDir\nThe path to the folder to save generated artifacts\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Output\n\nRequired: False\nPosition: 2\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nPath where you want to store the log outputs generated from the compiler\n\nAlso used as the path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 3\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModuleCompile\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetaDataDir\nThe path to the meta data directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ReferenceDir\nThe full path of a folder containing all assemblies referenced from X++ code\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:BinDirTools\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### [PsCustomObject]\n## NOTES\nTags: Compile, Model, Servicing, Report, Reports\n\nAuthor: Ievgen Miroshnikov (@IevgenMir)\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365ProcessModule.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365ProcessModule\n\n## SYNOPSIS\nProcess a specific or multiple modules (compile, deploy reports and sync)\n\n## SYNTAX\n\n```\nInvoke-D365ProcessModule [-Module] <String> [-ExecuteCompile] [-ExecuteSync] [-ExecuteDeployReports]\n [[-OutputDir] <String>] [[-LogPath] <String>] [[-MetaDataDir] <String>] [[-ReferenceDir] <String>]\n [[-BinDir] <String>] [-ShowOriginalProgress] [-OutputCommandOnly] [<CommonParameters>]\n```\n\n## DESCRIPTION\nProcess a specific or multiple modules by invoking the following functions (based on flags)\n- Invoke-D365ModuleFullCompile function\n- Publish-D365SsrsReport to deploy the reports of a module\n- Invoke-D365DBSyncPartial to sync the table and extension elements for module\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365ProcessModule -Module \"Application*Adaptor\" -ExecuteCompile\n```\n\nRetrieve the list of installed packages / modules where the name fits the search \"Application*Adaptor\".\n\nFor every value of the list perform the following:\n* Invoke-D365ModuleFullCompile with the needed parameters to compile current module value package.\n\nThe default output from all the different steps will be silenced.\n\n### EXAMPLE 2\n```\nInvoke-D365ProcessModule -Module \"Application*Adaptor\" -ExecuteSync\n```\n\nRetrieve the list of installed packages / modules where the name fits the search \"Application*Adaptor\".\n\nFor every value of the list perform the following:\n* Invoke-D365DBSyncPartial with the needed parameters to sync current module value table and extension elements.\n\nThe default output from all the different steps will be silenced.\n\n### EXAMPLE 3\n```\nInvoke-D365ProcessModule -Module \"Application*Adaptor\" -ExecuteDeployReports\n```\n\nRetrieve the list of installed packages / modules where the name fits the search \"Application*Adaptor\".\n\nFor every value of the list perform the following:\n* Publish-D365SsrsReport with the required parameters to deploy all reports of current module\n\nThe default output from all the different steps will be silenced.\n\n### EXAMPLE 4\n```\nInvoke-D365ProcessModule -Module \"Application*Adaptor\" -ExecuteCompile -ExecuteSync -ExecuteDeployReports\n```\n\nRetrieve the list of installed packages / modules where the name fits the search \"Application*Adaptor\".\n\nFor every value of the list perform the following:\n* Invoke-D365ModuleFullCompile with the needed parameters to compile current module package.\n* Invoke-D365DBSyncPartial with the needed parameters to sync current module table and extension elements.\n* Publish-D365SsrsReport with the required parameters to deploy all reports of current module\n\nThe default output from all the different steps will be silenced.\n\n## PARAMETERS\n\n### -Module\nName of the module that you want to process\n\nAccepts wildcards for searching.\nE.g.\n-Module \"Application*Adaptor\"\n\nDefault value is \"*\" which will search for all modules\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: ModuleName\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ExecuteCompile\nSwitch/flag to determine if the compile function should be executed for requested modules\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ExecuteSync\nSwitch/flag to determine if the databasesync function should be executed for requested modules\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ExecuteDeployReports\nSwitch/flag to determine if the deploy reports function should be executed for requested modules\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputDir\nThe path to the folder to save assemblies\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Output\n\nRequired: False\nPosition: 2\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nPath where you want to store the log outputs generated from the compiler\n\nAlso used as the path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 3\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModuleCompile\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetaDataDir\nThe path to the meta data directory for the environment\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ReferenceDir\nThe full path of a folder containing all assemblies referenced from X++ code\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:MetaDataDir\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:BinDirTools\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Compile, Model, Servicing, Database, Synchronization\n\nAuthor: Jasper Callens - Cegeka\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365ReArmWindows.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365ReArmWindows\n\n## SYNOPSIS\nInvokes the Rearm of Windows license\n\n## SYNTAX\n\n```\nInvoke-D365ReArmWindows [-Restart] [<CommonParameters>]\n```\n\n## DESCRIPTION\nFunction used for invoking the rearm functionality inside Windows\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365ReArmWindows\n```\n\nThis will re arm the Windows installation if there is any activation retries left\n\n### EXAMPLE 2\n```\nInvoke-D365ReArmWindows -Restart\n```\n\nThis will re arm the Windows installation if there is any activation retries left and restart the computer.\n\n## PARAMETERS\n\n### -Restart\nInstruct the cmdlet to restart the machine\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365RunbookAnalyzer.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365RunbookAnalyzer\n\n## SYNOPSIS\nAnalyze the runbook\n\n## SYNTAX\n\n### Default (Default)\n```\nInvoke-D365RunbookAnalyzer -Path <String> [<CommonParameters>]\n```\n\n### FailedOnlyAsObjects\n```\nInvoke-D365RunbookAnalyzer -Path <String> [-FailedOnlyAsObjects] [<CommonParameters>]\n```\n\n### FailedOnly\n```\nInvoke-D365RunbookAnalyzer -Path <String> [-FailedOnly] [<CommonParameters>]\n```\n\n## DESCRIPTION\nGet all the important details from a failed runbook\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365RunbookAnalyzer -Path \"C:\\DynamicsAX\\InstallationRecords\\Runbooks\\Runbook.xml\"\n```\n\nThis will analyze the Runbook.xml and output all the details about failed steps, the connected error logs and all the unprocessed steps.\n\n### EXAMPLE 2\n```\nGet-D365Runbook -Latest | Invoke-D365RunbookAnalyzer\n```\n\nThis will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\n\n### EXAMPLE 3\n```\nGet-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnly\n```\n\nThis will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\nThe output from Invoke-D365RunbookAnalyzer will only contain failed steps.\n\n### EXAMPLE 4\n```\nGet-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnlyAsObjects\n```\n\nThis will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\nThe output from Invoke-D365RunbookAnalyzer will only contain failed steps.\nThe output will be formatted as PSCustomObjects, to be used as variables or piping.\n\n### EXAMPLE 5\n```\nGet-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnlyAsObjects | Get-D365RunbookLogFile -Path \"C:\\Temp\\PU35\" -OpenInEditor\n```\n\nThis will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\nThe output from Invoke-D365RunbookAnalyzer will only contain failed steps.\nThe Get-D365RunbookLogFile will open all log files for the failed step.\n\n### EXAMPLE 6\n```\nGet-D365Runbook -Latest | Invoke-D365RunbookAnalyzer | Out-File \"C:\\Temp\\d365fo.tools\\runbook-analyze-results.xml\"\n```\n\nThis will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details.\nThe output will be saved into the \"C:\\Temp\\d365fo.tools\\runbook-analyze-results.xml\" file.\n\n### EXAMPLE 7\n```\nGet-D365Runbook -Latest | Backup-D365Runbook -Force | Invoke-D365RunbookAnalyzer\n```\n\nThis will get the latest runbook from the default location.\nThis will backup the file onto the default \"c:\\temp\\d365fo.tools\\runbookbackups\\\".\nThis will start the Runbook Analyzer on the backup file.\n\n## PARAMETERS\n\n### -Path\nPath to the runbook file that you work against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### -FailedOnly\nInstruct the cmdlet to only output failed steps\n\n```yaml\nType: SwitchParameter\nParameter Sets: FailedOnly\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FailedOnlyAsObjects\nInstruct the cmdlet to only output failed steps as objects\n\n```yaml\nType: SwitchParameter\nParameter Sets: FailedOnlyAsObjects\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### System.String\n## NOTES\nTags: Runbook, Servicing, Hotfix, DeployablePackage, Deployable Package, InstallationRecordsDirectory, Installation Records Directory\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365SCDPBundleInstall.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365SCDPBundleInstall\n\n## SYNOPSIS\nInvoke the SCDPBundleInstall.exe file\n\n## SYNTAX\n\n### InstallOnly (Default)\n```\nInvoke-D365SCDPBundleInstall [-InstallOnly] [-Path] <String> [[-MetaDataDir] <String>] [-ShowModifiedFiles]\n [-ShowProgress] [<CommonParameters>]\n```\n\n### Tfs\n```\nInvoke-D365SCDPBundleInstall [[-Command] <String>] [-Path] <String> [[-MetaDataDir] <String>]\n [[-TfsWorkspaceDir] <String>] [[-TfsUri] <String>] [-ShowModifiedFiles] [-ShowProgress] [<CommonParameters>]\n```\n\n## DESCRIPTION\nA cmdlet that wraps some of the cumbersome work of installing updates / hotfixes into a streamlined process\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365SCDPBundleInstall -Path \"c:\\temp\\HotfixPackageBundle.axscdppkg\" -InstallOnly\n```\n\nThis will install the \"HotfixPackageBundle.axscdppkg\" into the default PackagesLocalDirectory location on the machine.\n\n## PARAMETERS\n\n### -InstallOnly\nInstructs the cmdlet to only run the Install option and ignore any TFS / VSTS folders and source control in general\n\nUse it when testing an update on a local development machine (VM) / onebox\n\n```yaml\nType: SwitchParameter\nParameter Sets: InstallOnly\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Command\nThe command / job you want the cmdlet to execute\n\nValid options are:\nPrepare\nInstall\n\nDefault value is \"Prepare\"\n\n```yaml\nType: String\nParameter Sets: Tfs\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: Prepare\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Path\nPath to the update package that you want to install into the environment\n\nThe cmdlet only supports an already extracted \".axscdppkg\" file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File, Hotfix\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetaDataDir\nThe path to the meta data directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: \"$Script:MetaDataDir\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -TfsWorkspaceDir\nThe path to the TFS Workspace directory that you want to work against\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: Tfs\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: \"$Script:MetaDataDir\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -TfsUri\nThe URI for the TFS Team Site / VSTS Portal that you want to work against\n\nDefault URI is the one that is configured from inside Visual Studio\n\n```yaml\nType: String\nParameter Sets: Tfs\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: \"$Script:TfsUri\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowModifiedFiles\nSwitch to instruct the cmdlet to show all the modified files afterwards\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowProgress\nSwitch to instruct the cmdlet to output progress details while servicing the installation\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Hotfix, Hotfixes, Updates, Prepare, VSTS, axscdppkg\n\nAuthor: Mötz Jensen (@splaxi)\n\nAuthor: Tommy Skaue (@skaue)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365SDPInstall.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365SDPInstall\n\n## SYNOPSIS\nInstall a Software Deployable Package (SDP)\n\n## SYNTAX\n\n### QuickInstall (Default)\n```\nInvoke-D365SDPInstall [-Path] <String> [[-MetaDataDir] <String>] [-QuickInstallAll] [[-Step] <Int32>]\n [[-RunbookId] <String>] [-LogPath <String>] [-ShowOriginalProgress] [-OutputCommandOnly]\n [-TopologyFile <String>] [-UseExistingTopologyFile] [-IncludeFallbackRetailServiceModels] [-Force]\n [-ForceFallbackServiceModels] [<CommonParameters>]\n```\n\n### DevInstall\n```\nInvoke-D365SDPInstall [-Path] <String> [[-MetaDataDir] <String>] [-DevInstall] [[-Step] <Int32>]\n [[-RunbookId] <String>] [-LogPath <String>] [-ShowOriginalProgress] [-OutputCommandOnly]\n [-TopologyFile <String>] [-UseExistingTopologyFile] [-IncludeFallbackRetailServiceModels] [-Force]\n [-ForceFallbackServiceModels] [<CommonParameters>]\n```\n\n### Manual\n```\nInvoke-D365SDPInstall [-Path] <String> [[-MetaDataDir] <String>] [-Command] <String> [[-Step] <Int32>]\n [[-RunbookId] <String>] [-LogPath <String>] [-ShowOriginalProgress] [-OutputCommandOnly]\n [-TopologyFile <String>] [-UseExistingTopologyFile] [-IncludeFallbackRetailServiceModels] [-Force]\n [-ForceFallbackServiceModels] [<CommonParameters>]\n```\n\n### UDEInstall\n```\nInvoke-D365SDPInstall [-Path] <String> [[-MetaDataDir] <String>] [[-Step] <Int32>] [[-RunbookId] <String>]\n [-LogPath <String>] [-ShowOriginalProgress] [-OutputCommandOnly] [-TopologyFile <String>]\n [-UseExistingTopologyFile] [-UnifiedDevelopmentEnvironment] [-IncludeFallbackRetailServiceModels] [-Force]\n [-ForceFallbackServiceModels] [<CommonParameters>]\n```\n\n## DESCRIPTION\nA cmdlet that wraps some of the cumbersome work into a streamlined process.\nThe process for a legacy (i.e.\nnon unified) environment are detailed in the Microsoft documentation here:\nhttps://docs.microsoft.com/en-us/dynamics365/unified-operations/dev-itpro/deployment/install-deployable-package\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365SDPInstall -Path \"c:\\temp\\package.zip\" -QuickInstallAll\n```\n\nThis will install the package contained in the c:\\temp\\package.zip file using a runbook in memory while executing.\n\n### EXAMPLE 2\n```\nInvoke-D365SDPInstall -Path \"c:\\temp\\\" -DevInstall\n```\n\nThis will install the extracted package in c:\\temp\\ using a runbook in memory while executing.\n\nThis command is to be used on Microsoft Hosted Tier1 development environment, where you don't have access to the administrator user account on the vm.\n\n### EXAMPLE 3\n```\nInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command SetTopology\n```\n\nPS C:\\\\\\> Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command Generate -RunbookId 'MyRunbook'\nPS C:\\\\\\> Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command Import -RunbookId 'MyRunbook'\nPS C:\\\\\\> Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command Execute -RunbookId 'MyRunbook'\n\nManual operations that first create Topology XML from current environment, then generate runbook with id 'MyRunbook', then import it and finally execute it.\n\n### EXAMPLE 4\n```\nInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RunAll\n```\n\nCreate Topology XML from current environment.\nUsing default runbook id 'Runbook' and run all the operations from generate, to import to execute.\n\n### EXAMPLE 5\n```\nInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RerunStep -Step 18 -RunbookId 'MyRunbook'\n```\n\nRerun runbook with id 'MyRunbook' from step 18.\n\n### EXAMPLE 6\n```\nInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command SetStepComplete -Step 24 -RunbookId 'MyRunbook'\n```\n\nMark step 24 complete in runbook with id 'MyRunbook' and continue the runbook from the next step.\n\n### EXAMPLE 7\n```\nInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command SetTopology -TopologyFile \"c:\\temp\\MyTopology.xml\"\n```\n\nUpdate the MyTopology.xml file with all the installed services on the machine.\n\n### EXAMPLE 8\n```\nInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RunAll -TopologyFile \"c:\\temp\\MyTopology.xml\" -UseExistingTopologyFile\n```\n\nRun all manual steps in one single operation using the MyTopology.xml file.\nThe topology file is not updated.\n\n### EXAMPLE 9\n```\nInvoke-D365SDPInstall -Path \"c:\\temp\\\" -MetaDataDir \"c:\\MyRepository\\Metadata\" -UnifiedDevelopmentEnvironment\n```\n\nInstall the modules contained in the c:\\temp\\ directory into the c:\\MyRepository\\Metadata directory.\n\n### EXAMPLE 10\n```\nInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RunAll -IncludeFallbackRetailServiceModels\n```\n\nCreate Topology XML from current environment.\nIf the current environment does not have the information about the installed service models, a fallback list of known service model names will be used.\nThis fallback list includes the retail service models.\nUsing default runbook id 'Runbook' and run all the operations from generate, to import to execute.\n\n### EXAMPLE 11\n```\nInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RunAll -ForceFallbackServiceModels\n```\n\nCreate Topology XML from current environment.\nIf the current environment does have no or only partial information about the installed service models, a fallback list of known service model names will be used.\nThis fallback list does not include the retail service models.\nUsing default runbook id 'Runbook' and run all the operations from generate, to import to execute.\n\n## PARAMETERS\n\n### -Path\nPath to the update package that you want to install into the environment\n\nThe cmdlet supports a path to a zip-file or directory with the unpacked contents.\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File, Hotfix\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetaDataDir\nThe path to the meta data directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: \"$Script:MetaDataDir\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -QuickInstallAll\nUse this switch to let the runbook reside in memory.\nYou will not get a runbook on disc which you can examine for steps\n\n```yaml\nType: SwitchParameter\nParameter Sets: QuickInstall\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DevInstall\nUse this when running on developer box without administrator privileges (Run As Administrator)\n\n```yaml\nType: SwitchParameter\nParameter Sets: DevInstall\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Command\nThe command you want the cmdlet to execute when it runs the AXUpdateInstaller.exe\n\nValid options are:\nSetTopology\nGenerate\nImport\nExecute\nRunAll\nReRunStep\nSetStepComplete\nExport\nVersionCheck\n\nThe default value is \"SetTopology\"\n\n```yaml\nType: String\nParameter Sets: Manual\nAliases:\n\nRequired: True\nPosition: 4\nDefault value: SetTopology\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Step\nThe step number that you want to work against\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: 0\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RunbookId\nThe runbook id of the runbook that you want to work against\n\nDefault value is \"Runbook\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: Runbook\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nThe path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: Named\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\SdpInstall\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -TopologyFile\nProvide a custom topology file to use.\nBy default, the cmdlet will use the DefaultTopologyData.xml file in the package directory.\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: DefaultTopologyData.xml\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -UseExistingTopologyFile\nUse this switch to indicate that the topology file is already updated and should not be updated again.\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -UnifiedDevelopmentEnvironment\nUse this switch to install the package in a Unified Development Environment (UDE).\n\n```yaml\nType: SwitchParameter\nParameter Sets: UDEInstall\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -IncludeFallbackRetailServiceModels\nInclude fallback retail service models in the topology file\n\nThis parameter is to support backward compatibility in this scenario:\nInstalling the first update on a local VHD where the information about the installed service\nmodels may not be available and where the retail components are installed.\nMore information about this can be found at https://github.com/d365collaborative/d365fo.tools/issues/878\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nInstruct the cmdlet to overwrite the \"extracted\" folder if it exists\n\nUsed when the input is a zip file, that will auto extract to a folder named like the zip file.\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ForceFallbackServiceModels\nForce the use of the fallback list of known service model names\n\nThis parameter supports update scenarios primarily on local VHDs where the information about\nthe installed service models may be incomplete.\nIn such a case, the user receives a warning\nand a suggestion to use this parameter.\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Tommy Skaue (@skaue)\nAuthor: Mötz Jensen (@Splaxi)\nAuthor: Florian Hopfner (@FH-Inway)\n\nInspired by blogpost http://dev.goshoom.net/en/2016/11/installing-deployable-packages-with-powershell/\n\n## RELATED LINKS\n\n[Invoke-D365SDPInstallUDE]()\n\n"
  },
  {
    "path": "docs/Invoke-D365SDPInstallUDE.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365SDPInstallUDE\n\n## SYNOPSIS\nInstall a Software Deployable Package (SDP) in a unified development environment\n\n## SYNTAX\n\n```\nInvoke-D365SDPInstallUDE [-Path] <String> [-MetaDataDir] <String> [-LogPath <String>] [-Force]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nA cmdlet that wraps some of the cumbersome work into a streamlined process.\nIt first checks if the package is a zip file and extracts it if necessary.\nThen it checks if the package contains the necessary files and modules.\nFinally, it extracts the module zip files into the metadata directory.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365SDPInstallUDE -Path \"c:\\temp\\package.zip\" -MetaDataDir \"c:\\MyRepository\\Metadata\"\n```\n\nThis will install the modules contained in the c:\\temp\\package.zip file into the c:\\MyRepository\\Metadata directory.\n\n## PARAMETERS\n\n### -Path\nPath to the package that you want to install into the environment\n\nThe cmdlet supports a path to a zip-file or directory with the unpacked contents.\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File, Hotfix\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetaDataDir\nThe path to the meta data directory for the environment\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nThe path where the log file(s) will be saved\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: Named\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\SdpInstall\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nInstruct the cmdlet to overwrite the \"extracted\" folder if it exists\n\nUsed when the input is a zip file, that will auto extract to a folder named like the zip file.\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Florian Hopfner (@FH-Inway)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365SeleniumDownload.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365SeleniumDownload\n\n## SYNOPSIS\nDownloads the Selenium web driver files and deploys them to the specified destinations.\n\n## SYNTAX\n\n```\nInvoke-D365SeleniumDownload [-RegressionSuiteAutomationTool] [-PerfSDK] [<CommonParameters>]\n```\n\n## DESCRIPTION\nDownloads the Selenium web driver files and deploys them to the specified destinations.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365SeleniumDownload -RegressionSuiteAutomationTool -PerfSDK\n```\n\nThis will download the Selenium zip archives and extract the files into both the Regression Suite Automation Tool folder and the PerfSDK folder.\n\n## PARAMETERS\n\n### -RegressionSuiteAutomationTool\nSwitch to specify if the Selenium files need to be installed in the Regression Suite Automation Tool folder.\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PerfSDK\nSwitch to specify if the Selenium files need to be installed in the PerfSDK folder.\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Kenny Saelen (@kennysaelen)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365SqlScript.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365SqlScript\n\n## SYNOPSIS\nExecute a SQL Script or a SQL Command\n\n## SYNTAX\n\n### FilePath\n```\nInvoke-D365SqlScript [-FilePath] <String> [-DatabaseServer <String>] [-DatabaseName <String>]\n [-SqlUser <String>] [-SqlPwd <String>] [-TrustedConnection <Boolean>] [-EnableException] [-NoPooling]\n [<CommonParameters>]\n```\n\n### Command\n```\nInvoke-D365SqlScript [-Command] <String> [-DatabaseServer <String>] [-DatabaseName <String>]\n [-SqlUser <String>] [-SqlPwd <String>] [-TrustedConnection <Boolean>] [-EnableException] [-NoPooling]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nExecute a SQL Script or a SQL Command against the D365FO SQL Server database\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365SqlScript -FilePath \"C:\\temp\\d365fo.tools\\DeleteUser.sql\"\n```\n\nThis will execute the \"C:\\temp\\d365fo.tools\\DeleteUser.sql\" against the registered SQL Server on the machine.\n\n### EXAMPLE 2\n```\nInvoke-D365SqlScript -Command \"DELETE FROM SALESTABLE WHERE RECID = 123456789\"\n```\n\nThis will execute \"DELETE FROM SALESTABLE WHERE RECID = 123456789\" against the registered SQL Server on the machine.\n\n### EXAMPLE 3\n```\nInvoke-D365SqlScript -Command \"DELETE FROM SALESTABLE WHERE RECID = 123456789\" -NoPooling\n```\n\nThis will execute \"DELETE FROM SALESTABLE WHERE RECID = 123456789\" against the registered SQL Server on the machine.\nIt will not use connection pooling.\n\n## PARAMETERS\n\n### -FilePath\nPath to the file containing the SQL Script that you want executed\n\n```yaml\nType: String\nParameter Sets: FilePath\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Command\nSQL command that you want executed\n\n```yaml\nType: String\nParameter Sets: Command\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -TrustedConnection\nSwitch to instruct the cmdlet whether the connection should be using Windows Authentication or not\n\n```yaml\nType: Boolean\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -NoPooling\nShould the connection use connection pooling or not\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@splaxi)\n\nAuthor: Caleb Blanchard (@daxcaleb)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365SysFlushAodCache.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365SysFlushAodCache\n\n## SYNOPSIS\nInvoke the SysFlushAos class\n\n## SYNTAX\n\n```\nInvoke-D365SysFlushAodCache [[-Url] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nInvoke the runnable class SysFlushAos to clear the AOD cache\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365SysFlushAodCache\n```\n\nThis will a call against the default URL for the machine and\nhave it execute the SysFlushAOD class\n\n## PARAMETERS\n\n### -Url\nURL to the Dynamics 365 instance you want to clear the AOD cache on\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365SysRunnerClass.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365SysRunnerClass\n\n## SYNOPSIS\nStart a browser session that executes SysRunnerClass\n\n## SYNTAX\n\n```\nInvoke-D365SysRunnerClass [-ClassName] <String> [[-Company] <String>] [[-Url] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nMakes it possible to call any runnable class directly from the browser, without worrying about the details\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365SysRunnerClass -ClassName SysFlushAOD\n```\n\nWill execute the SysRunnerClass and have it execute the SysFlushAOD class and will run it against the \"DAT\" (default value) company\n\n### EXAMPLE 2\n```\nInvoke-D365SysRunnerClass -ClassName SysFlushAOD -Company \"USMF\"\n```\n\nWill execute the SysRunnerClass and have it execute the SysFlushAOD class and will run it against the \"USMF\" company\n\n### EXAMPLE 3\n```\nInvoke-D365SysRunnerClass -ClassName SysFlushAOD -Url https://Test.cloud.onebox.dynamics.com\n```\n\nWill execute the SysRunnerClass and have it execute the SysFlushAOD class and will run it against the \"DAT\" company, on the https://Test.cloud.onebox.dynamics.com URL\n\n## PARAMETERS\n\n### -ClassName\nThe name of the class you want to execute\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Company\nThe company for which you want to execute the class against\n\nDefault value is: \"DAT\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:Company\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Url\nThe URL you want to execute against\n\nDefault value is the Fully Qualified Domain Name registered on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:Url\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365TableBrowser.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365TableBrowser\n\n## SYNOPSIS\nStart a browser session that will show the table browser\n\n## SYNTAX\n\n```\nInvoke-D365TableBrowser [-TableName] <String> [[-Company] <String>] [[-Url] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nMakes it possible to call the table browser for a given table directly from the web browser, without worrying about the details\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365TableBrowser -TableName SalesTable\n```\n\nWill open the table browser and show all the records in Sales Table from the \"DAT\" company (default value).\n\n### EXAMPLE 2\n```\nInvoke-D365TableBrowser -TableName SalesTable -Company \"USMF\"\n```\n\nWill open the table browser and show all the records in Sales Table from the \"USMF\" company.\n\n## PARAMETERS\n\n### -TableName\nThe name of the table you want to see the rows for\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Company\nThe company for which you want to see the data from in the given table\n\nDefault value is: \"DAT\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:Company\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Url\nThe URL you want to execute against\n\nDefault value is the Fully Qualified Domain Name registered on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:Url\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\nThe cmdlet supports piping and can be used in advanced scenarios.\nSee more on github and the wiki pages.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365VisualStudioCompilerResultAnalyzer.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365VisualStudioCompilerResultAnalyzer\n\n## SYNOPSIS\nAnalyze the Visual Studio compiler output log\n\n## SYNTAX\n\n```\nInvoke-D365VisualStudioCompilerResultAnalyzer [[-Module] <String>] [[-OutputPath] <String>] [-SkipWarnings]\n [-SkipTasks] [[-PackageDirectory] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nAnalyze the Visual Studio compiler output log and generate an excel file contain worksheets per type: Errors, Warnings, Tasks\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365VisualStudioCompilerResultAnalyzer\n```\n\nThis will analyse all compiler output log files generated from Visual Studio.\n\nA result set example:\n\nFile                                                            Filename\n----                                                            --------\nc:\\temp\\d365fo.tools\\ApplicationCommon-CompilerResults.xlsx     ApplicationCommon-CompilerResults.xlsx\nc:\\temp\\d365fo.tools\\ApplicationFoundation-CompilerResults.xlsx ApplicationFoundation-CompilerResults.xlsx\nc:\\temp\\d365fo.tools\\ApplicationPlatform-CompilerResults.xlsx   ApplicationPlatform-CompilerResults.xlsx\nc:\\temp\\d365fo.tools\\ApplicationSuite-CompilerResults.xlsx      ApplicationSuite-CompilerResults.xlsx\nc:\\temp\\d365fo.tools\\ApplicationWorkspaces-CompilerResults.xlsx ApplicationWorkspaces-CompilerResults.xlsx\n\n### EXAMPLE 2\n```\nInvoke-D365VisualStudioCompilerResultAnalyzer -SkipWarnings\n```\n\nThis will analyse all compiler output log files generated from Visual Studio.\nIt will exclude all warnings from the output.\n\nA result set example:\n\nFile                                                            Filename\n----                                                            --------\nc:\\temp\\d365fo.tools\\ApplicationCommon-CompilerResults.xlsx     ApplicationCommon-CompilerResults.xlsx\nc:\\temp\\d365fo.tools\\ApplicationFoundation-CompilerResults.xlsx ApplicationFoundation-CompilerResults.xlsx\nc:\\temp\\d365fo.tools\\ApplicationPlatform-CompilerResults.xlsx   ApplicationPlatform-CompilerResults.xlsx\nc:\\temp\\d365fo.tools\\ApplicationSuite-CompilerResults.xlsx      ApplicationSuite-CompilerResults.xlsx\nc:\\temp\\d365fo.tools\\ApplicationWorkspaces-CompilerResults.xlsx ApplicationWorkspaces-CompilerResults.xlsx\n\n### EXAMPLE 3\n```\nInvoke-D365VisualStudioCompilerResultAnalyzer -SkipTasks\n```\n\nThis will analyse all compiler output log files generated from Visual Studio.\nIt will exclude all tasks from the output.\n\nA result set example:\n\nFile                                                            Filename\n----                                                            --------\nc:\\temp\\d365fo.tools\\ApplicationCommon-CompilerResults.xlsx     ApplicationCommon-CompilerResults.xlsx\nc:\\temp\\d365fo.tools\\ApplicationFoundation-CompilerResults.xlsx ApplicationFoundation-CompilerResults.xlsx\nc:\\temp\\d365fo.tools\\ApplicationPlatform-CompilerResults.xlsx   ApplicationPlatform-CompilerResults.xlsx\nc:\\temp\\d365fo.tools\\ApplicationSuite-CompilerResults.xlsx      ApplicationSuite-CompilerResults.xlsx\nc:\\temp\\d365fo.tools\\ApplicationWorkspaces-CompilerResults.xlsx ApplicationWorkspaces-CompilerResults.xlsx\n\n## PARAMETERS\n\n### -Module\nName of the module that you want to work against\n\nDefault value is \"*\" which will search for all modules\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: ModuleName\n\nRequired: False\nPosition: 1\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputPath\nPath where you want the excel file (xlsx-file) saved to\n\nDefault value is: \"c:\\temp\\d365fo.tools\\\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SkipWarnings\nInstructs the cmdlet to skip warnings while analyzing the compiler output log file\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SkipTasks\nInstructs the cmdlet to skip tasks while analyzing the compiler output log file\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the directory containing the installed package / module\n\nDefault path is the same as the AOS service \"PackagesLocalDirectory\" directory\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Compiler, Build, Errors, Warnings, Tasks\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThis cmdlet is inspired by the work of \"Vilmos Kintera\" (twitter: @DAXRunBase)\n\nAll credits goes to him for showing how to extract these information\n\nHis blog can be found here:\nhttps://www.daxrunbase.com/blog/\n\nThe specific blog post that we based this cmdlet on can be found here:\nhttps://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/\n\nThe github repository containing the original scrips can be found here:\nhttps://github.com/DAXRunBase/PowerShell-and-Azure\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Invoke-D365WinRmCertificateRotation.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Invoke-D365WinRmCertificateRotation\n\n## SYNOPSIS\nRotate the certificate used for WinRM\n\n## SYNTAX\n\n```\nInvoke-D365WinRmCertificateRotation [[-MachineName] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nThere is a scenario where you might need to update the certificate that is being used for WinRM on your Tier1 environment\n\n1 year after you deploy your Tier1 environment, the original WinRM certificate expires and then LCS will be unable to communicate with your Tier1 environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365WinRmCertificateRotation\n```\n\nThis will update the certificate that is being used by WinRM.\nA new certificate is created with the current computer name.\nThe new certificate and its thumbprint will be configured for WinRM to use that going forward.\n\n## PARAMETERS\n\n### -MachineName\nThe DNS / Netbios name of the machine\n\nThe default value is: \"$env:COMPUTERNAME\" which translates into the current name of the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $env:COMPUTERNAME\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\nWe recommend that you do a full restart of the Tier1 environment when done.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/New-D365Bacpac.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# New-D365Bacpac\n\n## SYNOPSIS\nGenerate a bacpac file from a database\n\n## SYNTAX\n\n### ExportTier2 (Default)\n```\nNew-D365Bacpac [-ExportModeTier2] [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [-SqlUser] <String>\n [-SqlPwd] <String> [[-NewDatabaseName] <String>] [[-BacpacFile] <String>] [[-CustomSqlFile] <String>]\n [-DiagnosticFile <String>] [-ExportOnly] [-MaxParallelism <Int32>] [-ShowOriginalProgress]\n [-OutputCommandOnly] [-EnableException] [<CommonParameters>]\n```\n\n### ExportTier1\n```\nNew-D365Bacpac [-ExportModeTier1] [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>]\n [[-SqlPwd] <String>] [[-BackupDirectory] <String>] [[-NewDatabaseName] <String>] [[-BacpacFile] <String>]\n [[-CustomSqlFile] <String>] [-DiagnosticFile <String>] [-ExportOnly] [-MaxParallelism <Int32>]\n [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nTakes care of all the details and steps that is needed to create a valid bacpac file to move between Tier 1 (onebox or Azure hosted) and Tier 2 (MS hosted), or vice versa\n\nSupports to create a raw bacpac file without prepping.\nCan be used to automate backup from Tier 2 (MS hosted) environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365InstallSqlPackage\n```\n\nYou should always install the latest version of the SqlPackage.exe, which is used by New-D365Bacpac.\n\nThis will fetch the latest .Net Core Version of SqlPackage.exe and install it at \"C:\\temp\\d365fo.tools\\SqlPackage\".\n\n### EXAMPLE 2\n```\nNew-D365Bacpac -ExportModeTier1 -BackupDirectory c:\\Temp\\backup\\ -NewDatabaseName Testing1 -BacpacFile \"C:\\Temp\\Bacpac\\Testing1.bacpac\"\n```\n\nWill backup the \"AXDB\" database and restore is as \"Testing1\" again the localhost SQL Server.\nWill run the prepping process against the restored database.\nWill export a bacpac file to \"C:\\Temp\\Bacpac\\Testing1.bacpac\".\nWill delete the restored database.\nIt will use trusted connection (Windows authentication) while working against the SQL Server.\n\n### EXAMPLE 3\n```\nNew-D365Bacpac -ExportModeTier2 -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\" -NewDatabaseName Testing1 -BacpacFile C:\\Temp\\Bacpac\\Testing1.bacpac\n```\n\nWill create a copy the db database on the dbserver1 in Azure.\nWill run the prepping process against the copy database.\nWill export a bacpac file.\nWill delete the copy database.\n\n### EXAMPLE 4\n```\nNew-D365Bacpac -ExportModeTier2 -SqlUser User123 -SqlPwd \"Password123\" -NewDatabaseName Testing1 -BacpacFile \"C:\\Temp\\Bacpac\\Testing1.bacpac\"\n```\n\nNormally used for a Tier-2 export and preparation for Tier-1 import\n\nWill create a copy of the registered D365 database on the registered D365 Azure SQL DB instance.\nWill run the prepping process against the copy database.\nWill export a bacpac file.\nWill delete the copy database.\n\n### EXAMPLE 5\n```\nNew-D365Bacpac -ExportModeTier2 -SqlUser User123 -SqlPwd \"Password123\" -NewDatabaseName Testing1 -BacpacFile C:\\Temp\\Bacpac\\Testing1.bacpac -ExportOnly\n```\n\nWill export a bacpac file.\nThe bacpac should be able to restore back into the database without any preparing because it is coming from the environment from the beginning\n\n### EXAMPLE 6\n```\nNew-D365Bacpac -ExportModeTier1 -BackupDirectory c:\\Temp\\backup\\ -NewDatabaseName Testing1 -BacpacFile \"C:\\Temp\\Bacpac\\Testing1.bacpac\" -DiagnosticFile \"C:\\temp\\ExportLog.txt\"\n```\n\nWill backup the \"AXDB\" database and restore is as \"Testing1\" again the localhost SQL Server.\nWill run the prepping process against the restored database.\nWill export a bacpac file to \"C:\\Temp\\Bacpac\\Testing1.bacpac\".\nWill delete the restored database.\nIt will use trusted connection (Windows authentication) while working against the SQL Server.\n\nIt will output a diagnostic file to \"C:\\temp\\ExportLog.txt\".\n\n### EXAMPLE 7\n```\nNew-D365Bacpac -ExportModeTier1 -BackupDirectory c:\\Temp\\backup\\ -NewDatabaseName Testing1 -BacpacFile \"C:\\Temp\\Bacpac\\Testing1.bacpac\" -MaxParallelism 32\n```\n\nWill backup the \"AXDB\" database and restore is as \"Testing1\" again the localhost SQL Server.\nWill run the prepping process against the restored database.\nWill export a bacpac file to \"C:\\Temp\\Bacpac\\Testing1.bacpac\".\nWill delete the restored database.\nIt will use trusted connection (Windows authentication) while working against the SQL Server.\n\nIt will use 32 connections against the database server while generating the bacpac file.\n\n## PARAMETERS\n\n### -ExportModeTier1\nSwitch to instruct the cmdlet that the export will be done against a classic SQL Server installation\n\n```yaml\nType: SwitchParameter\nParameter Sets: ExportTier1\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ExportModeTier2\nSwitch to instruct the cmdlet that the export will be done against an Azure SQL DB instance\n\n```yaml\nType: SwitchParameter\nParameter Sets: ExportTier2\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: ExportTier2\nAliases:\n\nRequired: True\nPosition: 4\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n```yaml\nType: String\nParameter Sets: ExportTier1\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: ExportTier2\nAliases:\n\nRequired: True\nPosition: 5\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n```yaml\nType: String\nParameter Sets: ExportTier1\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -BackupDirectory\nThe path where to store the temporary backup file when the script needs to handle that\n\n```yaml\nType: String\nParameter Sets: ExportTier1\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: C:\\Temp\\d365fo.tools\\SqlBackups\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -NewDatabaseName\nThe name for the database the script is going to create when doing the restore process\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: \"$Script:DatabaseName`_export\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BacpacFile\nThe path where you want the cmdlet to store the bacpac file that will be generated\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File\n\nRequired: False\nPosition: 8\nDefault value: \"C:\\Temp\\d365fo.tools\\$DatabaseName.bacpac\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -CustomSqlFile\nThe path to a custom sql server script file that you want executed against the database before it is exported\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 9\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DiagnosticFile\nPath to where you want the export to output a diagnostics file to assist you in troubleshooting the export\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ExportOnly\nSwitch to instruct the cmdlet to either just create a dump bacpac file or run the prepping process first\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MaxParallelism\nSets SqlPackage.exe's degree of parallelism for concurrent operations running against a database.\nThe default value is 8.\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: 8\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nThe cmdlet supports piping and can be used in advanced scenarios.\nSee more on github and the wiki pages.\n\nAuthor: Rasmus Andersen (@ITRasmus)\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/New-D365CAReport.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# New-D365CAReport\n\n## SYNOPSIS\nGenerate the Customization's Analysis Report (CAR)\n\n## SYNTAX\n\n```\nNew-D365CAReport [[-OutputPath] <String>] [-Module] <String> [-Model] <String> [-SuffixWithModule]\n [[-BinDir] <String>] [[-MetaDataDir] <String>] [[-XmlLog] <String>] [-PackagesRoot] [[-LogPath] <String>]\n [-ShowOriginalProgress] [-OutputCommandOnly] [<CommonParameters>]\n```\n\n## DESCRIPTION\nA cmdlet that wraps some of the cumbersome work into a streamlined process\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nNew-D365CAReport -module \"ApplicationSuite\" -model \"MyOverLayerModel\"\n```\n\nThis will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module.\nIt will use the default value for the OutputPath parameter, which is \"c:\\temp\\d365fo.tools\\CAReport.xlsx\".\n\n### EXAMPLE 2\n```\nNew-D365CAReport -OutputPath \"c:\\temp\\CAReport.xlsx\" -module \"ApplicationSuite\" -model \"MyOverLayerModel\"\n```\n\nThis will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module.\nIt will use the \"c:\\temp\\CAReport.xlsx\" value for the OutputPath parameter.\n\n### EXAMPLE 3\n```\nNew-D365CAReport -module \"ApplicationSuite\" -model \"MyOverLayerModel\" -SuffixWithModule\n```\n\nThis will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module.\nIt will use the default value for the OutputPath parameter, which is \"c:\\temp\\d365fo.tools\\CAReport.xlsx\".\nIt will append the module name to the desired output file, which will then be \"c:\\temp\\d365fo.tools\\CAReport-ApplicationSuite.xlsx\".\n\n### EXAMPLE 4\n```\nNew-D365CAReport -OutputPath \"c:\\temp\\CAReport.xlsx\" -module \"ApplicationSuite\" -model \"MyOverLayerModel\" -PackagesRoot\n```\n\nThis will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module.\nIt will use the binary metadata to look for the module and model.\nIt will use the \"c:\\temp\\CAReport.xlsx\" value for the OutputPath parameter.\n\n## PARAMETERS\n\n### -OutputPath\nPath where you want the CAR file (xlsx-file) saved to\n\nDefault value is: \"c:\\temp\\d365fo.tools\\CAReport.xlsx\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Path, File\n\nRequired: False\nPosition: 1\nDefault value: (Join-Path $Script:DefaultTempPath \"CAReport.xlsx\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Module\nName of the Module to analyse\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: ModuleName, Package\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Model\nName of the Model to analyse\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SuffixWithModule\nInstruct the cmdlet to append the module name as a suffix to the desired output file name\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the AOS service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: \"$Script:PackageDirectory\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetaDataDir\nThe path to the meta data directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: \"$Script:MetaDataDir\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -XmlLog\nPath where you want to store the Xml log output generated from the best practice analyser\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: (Join-Path $Script:DefaultTempPath \"BPCheckLogcd.xml\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackagesRoot\nInstructs the cmdlet to use binary metadata\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nThe path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 7\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\CAReport\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Tommy Skaue (@Skaue)\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/New-D365EntraIntegration.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# New-D365EntraIntegration\n\n## SYNOPSIS\nEnable the Microsoft Entra ID integration on a cloud hosted environment (CHE).\n\n## SYNTAX\n\n### NewCertificate (Default)\n```\nNew-D365EntraIntegration -ClientId <String> [-CertificateName <String>] [-CertificateExpirationYears <Int32>]\n [-NewCertificateFile <String>] [-NewCertificatePrivateKeyFile <String>] [-CertificatePassword <SecureString>]\n [-Force] [-WhatIf] [-Confirm] [<CommonParameters>]\n```\n\n### ExistingCertificate\n```\nNew-D365EntraIntegration -ClientId <String> -ExistingCertificateFile <String>\n [-ExistingCertificatePrivateKeyFile <String>] [-CertificatePassword <SecureString>] [-Force] [-WhatIf]\n [-Confirm] [<CommonParameters>]\n```\n\n## DESCRIPTION\nEnable the Microsoft Entra ID integration by executing some of the steps described in https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/dev-tools/secure-developer-vm#external-integrations.\nThe integration can either be enabled with an existing certificate or a new self-signed certificate can be created.\nIf a new certificate is created and the integration is also to be enabled on other environments with the same certificate, a certificate password must be specified in order to create a certificate private key file.\n\nThe steps executed are:\n\n- 1) Create a self-signed certificate and save it to Desktop or use a provided certificate.\n- 2) Install the certificate to the \"LocalMachine\" certificate store.\n- 3) Grant NetworkService READ permission to the certificate (only on cloud-hosted environments).\n- 4) Update the web.config with the application ID and the thumbprint of the certificate.\n- 5) Add the application registration to the WIF config.\n- 6) Clear cached LCS configuration in AxDB.\n- 7) Restart the IIS service.\n\nTo execute the steps, the id of an Azure application must be provided.\nThe application must have the following API permissions:\n\n- Dynamics ERP - This permission is required to access finance and operations environments.\n- Microsoft Graph (User.Read.All and Group.Read.All permissions of the Application type).\n- Dynamics Lifecylce service (permission of type Delegated)\n\nThe URL of the finance and operations environment must also be added to the RedirectURI in the Authentication section of the Azure application.\nFinally, after running the cmdlet, if a new certificate was created, it must be uploaded to the Azure application.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nNew-D365EntraIntegration -ClientId e70cac82-6a7c-4f9e-a8b9-e707b961e986\n```\n\nEnables the Entra ID integration with a new self-signed certificate named \"CHEAuth\" which expires after 2 years.\n\n### EXAMPLE 2\n```\nNew-D365EntraIntegration -ClientId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -CertificateName \"SelfsignedCert\"\n```\n\nEnables the Entra ID integration with a new self-signed certificate with the name \"Selfsignedcert\" that expires after 2 years.\n\n### EXAMPLE 3\n```\nNew-D365EntraIntegration -AppId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -CertificateName \"SelfsignedCert\" -CertificateExpirationYears 1\n```\n\nEnables the Entra ID integration with a new self-signed certificate with the name \"SelfsignedCert\" that expires after 1 year.\n\n### EXAMPLE 4\n```\n$securePassword = Read-Host -AsSecureString -Prompt \"Enter the certificate password\"\n```\n\nPS C:\\\\\\> New-D365EntraIntegration -AppId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -CertificatePassword $securePassword\n\nEnables the Entra ID integration with a new self-signed certificate with the name \"CHEAuth\" that expires after 2 years, using the provided password to generate the private key of the certificate.\nThe certificate file and the private key file are saved to the Desktop of the current user.\n\n### EXAMPLE 5\n```\n$securePassword = Read-Host -AsSecureString -Prompt \"Enter the certificate password\"\n```\n\nPS C:\\\\\\> New-D365EntraIntegration -AppId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -ExistingCertificateFile \"C:\\Temp\\SelfsignedCert.cer\" -ExistingCertificatePrivateKeyFile \"C:\\Temp\\SelfsignedCert.pfx\" -CertificatePassword $securePassword\n\nEnables the Entra ID integration with the certificate file \"C:\\Temp\\SelfsignedCert.cer\", the private key file \"C:\\Temp\\SelfsignedCert.pfx\" and the provided password to install it.\n\n## PARAMETERS\n\n### -ClientId\nThe Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal.\nIt is assumed that an application with this id already exists in Azure.\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: AppId\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ExistingCertificateFile\nThe path to a certificate file.\nIf this parameter is provided, the cmdlet will not create a new certificate.\n\n```yaml\nType: String\nParameter Sets: ExistingCertificate\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ExistingCertificatePrivateKeyFile\nThe path to a certificate private key file.\nIf this parameter is not provided, the certificate can be installed to the certificate store, but the NetworkService cannot be granted READ permission.\n\n```yaml\nType: String\nParameter Sets: ExistingCertificate\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -CertificateName\nThe name for the certificate.\nBy default, it is named \"CHEAuth\".\n\n```yaml\nType: String\nParameter Sets: NewCertificate\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: CHEAuth\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -CertificateExpirationYears\nThe number of years the certificate is valid.\nBy default, it is valid for 2 years.\n\n```yaml\nType: Int32\nParameter Sets: NewCertificate\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: 2\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -NewCertificateFile\nThe path to the certificate file that will be created.\nBy default, it is created on the Desktop of the current user.\n\n```yaml\nType: String\nParameter Sets: NewCertificate\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: \"$env:USERPROFILE\\Desktop\\$CertificateName.cer\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -NewCertificatePrivateKeyFile\nThe path to the certificate private key file that will be created.\nBy default, it is created on the Desktop of the current user.\n\n```yaml\nType: String\nParameter Sets: NewCertificate\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: \"$env:USERPROFILE\\Desktop\\$CertificateName.pfx\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -CertificatePassword\nThe password for the certificate private key file.\nIf not provided when creating a new certificate, no private key file will be created.\nIf not provided when using an existing certificate, the private key file cannot be installed.\n\n```yaml\nType: SecureString\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nForces the execution of some of the steps.\nFor example, if a certificate with the same name already exists, it will be deleted and recreated.\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -WhatIf\nExecutes the cmdlet until the first operation that would change the state of the system, without executing that operation.\nSubsequent operations are likely to fail.\nThis is currently not fully implemented and should not be used.\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases: wi\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Confirm\nPrompts for confirmation before each operation of the cmdlet that changes the state of the system.\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases: cf\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### If a new certificate is created, the certificate file is placed on the Desktop of the current user.\n### It must be uploaded to the Azure Application.\n## NOTES\nTest-D365EntraIntegration can be used to validate an entra integration.\n\nAuthor: Øystein Brenna (@oysbre)\nAuthor: Florian Hopfner (@FH-Inway)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/New-D365ISVLicense.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# New-D365ISVLicense\n\n## SYNOPSIS\nCreate a license deployable package\n\n## SYNTAX\n\n```\nNew-D365ISVLicense [-LicenseFile] <String> [-Path <String>] [-OutputPath <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nCreate a deployable package with a license file inside\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nNew-D365ISVLicense -LicenseFile \"C:\\temp\\ISVLicenseFile.txt\"\n```\n\nThis will take the \"C:\\temp\\ISVLicenseFile.txt\" file and locate the \"ImportISVLicense.zip\" template file under the \"PackagesLocalDirectory\\bin\\CustomDeployablePackage\\\".\nIt will extract the \"ImportISVLicense.zip\", load the ISVLicenseFile.txt and compress (zip) the files into a deployable package.\nThe package will be exported to \"C:\\temp\\d365fo.tools\\ISVLicense.zip\"\n\n## PARAMETERS\n\n### -LicenseFile\nPath to the license file that you want to have inside a deployable package\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Path\nPath to the template zip file for creating a deployable package with a license file\n\nDefault path is the same as the aos service \"PackagesLocalDirectory\\bin\\CustomDeployablePackage\\ImportISVLicense.zip\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Template\n\nRequired: False\nPosition: Named\nDefault value: \"$Script:BinDirTools\\CustomDeployablePackage\\ImportISVLicense.zip\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputPath\nPath where you want the generated deployable package stored\n\nDefault value is: \"C:\\temp\\d365fo.tools\\ISVLicense.zip\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: C:\\temp\\d365fo.tools\\ISVLicense.zip\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@splaxi)\nAuthor: Szabolcs Eötvös\nAuthor: Florian Hopfner (@FH-Inway)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/New-D365ModuleToRemove.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# New-D365ModuleToRemove\n\n## SYNOPSIS\nCreate a new ModuleToRemove.txt file\n\n## SYNTAX\n\n```\nNew-D365ModuleToRemove [-Path] <String> [-Modules] <String[]> [<CommonParameters>]\n```\n\n## DESCRIPTION\nCreate a new ModuleToRemove.txt file based on a list of module names\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nNew-D365ModuleToRemove -Path C:\\Temp -Modules \"MyRemovedModule1\",\"MySecondRemovedModule\"\n```\n\nThis will create a new ModuleToRemove.txt file and fill in \"MyRemovedModule1\" and \"MySecondRemovedModule\" as the modules to remove.\nThe new file is stored at \"C:\\Temp\\ModuleToRemove.txt\"\n\n### EXAMPLE 2\n```\nNew-D365ModuleToRemove -Path C:\\Temp -Modules \"MyRemovedModule1\",\"MySecondRemovedModule\" | Add-D365ModuleToRemove -DeployablePackage C:\\Temp\\DeployablePackage.zip\n```\n\nThis will create a new ModuleToRemove.txt file and fill in \"MyRemovedModule1\" and \"MySecondRemovedModule\" as the modules to remove.\nThe file is then added to the \"C:\\Temp\\DeployablePackage.zip\" deployable package.\n\n## PARAMETERS\n\n### -Path\nPath to the ModuleToRemove.txt file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Folder\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Modules\nThe array with all the module names that you want to fill into the ModuleToRemove.txt file\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Florian Hopfner (@FH-Inway)\n\n## RELATED LINKS\n\n[Add-D365ModuleToRemove]()\n\n"
  },
  {
    "path": "docs/New-D365TopologyFile.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# New-D365TopologyFile\n\n## SYNOPSIS\nCreate a new topology file\n\n## SYNTAX\n\n```\nNew-D365TopologyFile [-Path] <String> [-Services] <String[]> [-NewPath] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\nBuild a new topology file based on a template and update the ServiceModelList\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nNew-D365TopologyFile -Path C:\\Temp\\DefaultTopologyData.xml -Services \"ALMService\",\"AOSService\",\"BIService\" -NewPath C:\\temp\\CurrentTopology.xml\n```\n\nThis will read the \"DefaultTopologyData.xml\" file and fill in \"ALMService\",\"AOSService\" and \"BIService\"\nas the services in the ServiceModelList tag.\nThe new file is stored at \"C:\\temp\\CurrentTopology.xml\"\n\n### EXAMPLE 2\n```\n$Services = @(Get-D365InstalledService | ForEach-Object {$_.Servicename})\n```\n\nPS C:\\\\\\> New-D365TopologyFile -Path C:\\Temp\\DefaultTopologyData.xml -Services $Services -NewPath C:\\temp\\CurrentTopology.xml\n\nThis will get all the services already installed on the machine.\nAfterwards the list is piped\nto New-D365TopologyFile where all services are import into the new topology file that is stored at \"C:\\temp\\CurrentTopology.xml\"\n\n## PARAMETERS\n\n### -Path\nPath to the template topology file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Services\nThe array with all the service names that you want to fill into the topology file\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -NewPath\nPath to where you want to save the new file after it has been created\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: NewFile\n\nRequired: True\nPosition: 4\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Publish-D365SsrsReport.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Publish-D365SsrsReport\n\n## SYNOPSIS\nDeploy Report\n\n## SYNTAX\n\n```\nPublish-D365SsrsReport [[-Module] <String[]>] [[-ReportName] <String[]>] [[-LogFile] <String>]\n [[-PackageDirectory] <String>] [[-ToolsBasePath] <String>] [[-ReportServerIp] <String[]>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nDeploy SSRS Report to SQL Server Reporting Services\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nPublish-D365SsrsReport -Module ApplicationSuite -ReportName TaxVatRegister.Report\n```\n\nThis will deploy the report which is named \"TaxVatRegister.Report\".\nThe cmdlet will look for the report inside the ApplicationSuite module.\nThe cmdlet will be using the default 127.0.0.1 while deploying the report.\n\n### EXAMPLE 2\n```\nPublish-D365SsrsReport -Module ApplicationSuite -ReportName *\n```\n\nThis will deploy the all reports from the ApplicationSuite module.\nThe cmdlet will be using the default 127.0.0.1 while deploying the report.\n\n## PARAMETERS\n\n### -Module\nName of the module that you want to works against\n\nAccepts an array of strings\n\nDefault value is \"*\" and will work against all modules loaded on the machine\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ReportName\nName of the report that you want to deploy\n\nDefault value is \"*\" and will deploy all reports from the module(s) that you speficied\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: *\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogFile\nPath to the file that should contain the logging information\n\nDefault value is \"c:\\temp\\d365fo.tools\\AxReportDeployment.log\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: (Join-Path $Script:DefaultTempPath \"AxReportDeployment.log\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PackageDirectory\nPath to the PackagesLocalDirectory\n\nDefault path is the same as the AOS Service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ToolsBasePath\nBase path to the folder containing the needed PowerShell manifests that the cmdlet utilizes\n\nDefault path is the same as the AOS Service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ReportServerIp\nIP Address of the server that has SQL Reporting Services installed\n\nDefault value is \"127.0.01\"\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: 127.0.0.1\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### [PsCustomObject]\n## NOTES\nTags: SSRS, Report, Reports, Deploy, Publish\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Publish-D365WebResources.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Publish-D365WebResources\n\n## SYNOPSIS\nDeploy web resources\n\n## SYNTAX\n\n```\nPublish-D365WebResources [[-PackageDirectory] <PathDirectoryParameter>]\n [[-AosServiceWebRootPath] <PathDirectoryParameter>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nDeploys the Dynamics 365 for Finance and Operations web resources to the AOS service web root path.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nPublish-D365WebResources\n```\n\nThis will deploy the web resources to the AOS service web root path.\n\n## PARAMETERS\n\n### -PackageDirectory\nPath to the package directory containing the web resources.\n\n```yaml\nType: PathDirectoryParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:PackageDirectory\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AosServiceWebRootPath\nPath to the AOS service web root path.\n\n```yaml\nType: PathDirectoryParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:AOSPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Florian Hopfner (@FH-Inway)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Register-D365AzureStorageConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Register-D365AzureStorageConfig\n\n## SYNOPSIS\nRegister Azure Storage Configurations\n\n## SYNTAX\n\n```\nRegister-D365AzureStorageConfig [[-ConfigStorageLocation] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nRegister all Azure Storage Configurations\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nRegister-D365AzureStorageConfig -ConfigStorageLocation \"System\"\n```\n\nThis will store all Azure Storage Configurations as defaults for all users on the machine.\n\n## PARAMETERS\n\n### -ConfigStorageLocation\nParameter used to instruct where to store the configuration objects\n\nThe default value is \"User\" and this will store all configuration for the active user\n\nValid options are:\n\"User\"\n\"System\"\n\n\"System\" will store the configuration as default for all users, so they can access the configuration objects\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: User\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Configuration, Azure, Storage\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Remove-D365BroadcastMessageConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Remove-D365BroadcastMessageConfig\n\n## SYNOPSIS\nRemove broadcast message configuration\n\n## SYNTAX\n\n```\nRemove-D365BroadcastMessageConfig [-Name] <String> [-Temporary] [<CommonParameters>]\n```\n\n## DESCRIPTION\nRemove a broadcast message configuration from the configuration store\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nRemove-D365BroadcastMessageConfig -Name \"UAT\"\n```\n\nThis will remove the broadcast message configuration name \"UAT\" from the machine.\n\n## PARAMETERS\n\n### -Name\nName of the broadcast message configuration you want to remove from the configuration store\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Temporary\nInstruct the cmdlet to only temporarily remove the broadcast message configuration from the configuration store\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Servicing, Broadcast, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Add-D365BroadcastMessageConfig]()\n\n[Clear-D365ActiveBroadcastMessageConfig]()\n\n[Get-D365ActiveBroadcastMessageConfig]()\n\n[Get-D365BroadcastMessageConfig]()\n\n[Send-D365BroadcastMessage]()\n\n[Set-D365ActiveBroadcastMessageConfig]()\n\n"
  },
  {
    "path": "docs/Remove-D365Database.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Remove-D365Database\n\n## SYNOPSIS\nRemoves a database\n\n## SYNTAX\n\n```\nRemove-D365Database [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>]\n [[-SqlPwd] <String>] [-EnableException] [-Force] [-WhatIf] [-Confirm] [<CommonParameters>]\n```\n\n## DESCRIPTION\nRemoves a database.\nBy default, if no other database is specified, the AxDB database will be removed.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nRemove-D365Database\n```\n\nThis will remove the \"AxDB\" database from the default SQL Server instance that is registered on the machine.\n\n### EXAMPLE 2\n```\nRemove-D365Database -DatabaseName \"ExportClone\"\n```\n\nThis will remove the \"ExportClone\" from the default SQL Server instance that is registered on the machine.\n\n## PARAMETERS\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nThis parameter will suppress the confirmation prompt.\nIt can be used as an alternative to -Confirm:$false\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -WhatIf\nThis parameter will simulate the actions of the command.\nNo changes will be made.\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases: wi\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Confirm\nThis parameter will prompt you for confirmation before executing steps of the command that have a medium impact.\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases: cf\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\nAuthor: Florian Hopfner (@FH-Inway)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Remove-D365LcsAssetFile.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Remove-D365LcsAssetFile\n\n## SYNOPSIS\nDelete asset from the LCS project Asset Library\n\n## SYNTAX\n\n```\nRemove-D365LcsAssetFile [[-ProjectId] <Int32>] [-AssetId] <String> [[-BearerToken] <String>]\n [[-LcsApiUri] <String>] [[-RetryTimeout] <TimeSpan>] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nDelete asset from the LCS project Asset Library\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nRemove-D365LcsAssetFile -ProjectId 123456789 -BearerToken \"JldjfafLJdfjlfsalfd...\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\" -AssetId \"812bcb0e-23fb-476d-8a92-985f20a704b9\"\n```\n\nThis will delete the Asset file from the LCS Asset Library.\nThe LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal.\nThe request will authenticate with the BearerToken \"JldjfafLJdfjlfsalfd...\".\nThe http request will be going to the LcsApiUri \"https://lcsapi.lcs.dynamics.com\" (NON-EUROPE).\n\n## PARAMETERS\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:LcsApiProjectId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AssetId\nLCS Id of the file that you are looking for\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Token\n\nRequired: False\nPosition: 3\nDefault value: $Script:LcsApiBearerToken\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\nDefault value can be configured using Set-D365LcsApiConfig\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:LcsApiLcsApiUri\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RetryTimeout\nThe retry timeout, before the cmdlet should quit retrying based on the 429 status code\n\nNeeds to be provided in the timspan notation:\n\"hh:mm:ss\"\n\nhh is the number of hours, numerical notation only\nmm is the number of minutes\nss is the numbers of seconds\n\nEach section of the timeout has to valid, e.g.\nhh can maximum be 23\nmm can maximum be 59\nss can maximum be 59\n\nNot setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint\n\n```yaml\nType: TimeSpan\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: 00:00:00\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Oleksandr Nikolaiev (@onikolaiev)\n\n## RELATED LINKS\n\n[Get-D365LcsApiConfig]()\n\n[Get-D365LcsApiToken]()\n\n[Invoke-D365LcsApiRefreshToken]()\n\n[Set-D365LcsApiConfig]()\n\n[Remove-LcsAssetFile]()\n\n"
  },
  {
    "path": "docs/Remove-D365Model.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Remove-D365Model\n\n## SYNOPSIS\nRemove a model from Dynamics 365 for Finance & Operations\n\n## SYNTAX\n\n```\nRemove-D365Model [-Model] <String> [[-BinDir] <String>] [[-MetaDataDir] <String>] [-DeleteFolders]\n [-ShowOriginalProgress] [-OutputCommandOnly] [<CommonParameters>]\n```\n\n## DESCRIPTION\nRemove a model from a Dynamics 365 for Finance & Operations environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nRemove-D365Model -Model CustomModelName\n```\n\nThis will remove the \"CustomModelName\" model from the D365FO environment.\nIt will NOT remove the folders inside the PackagesLocalDirectory location.\n\n### EXAMPLE 2\n```\nRemove-D365Model -Model CustomModelName -DeleteFolders\n```\n\nThis will remove the \"CustomModelName\" model from the D365FO environment.\nIt will remove the folders inside the PackagesLocalDirectory location.\nThis is helpful when dealing with source control and you want to remove the model entirely.\n\n## PARAMETERS\n\n### -Model\nName of the model that you want to work against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the AOS service PackagesLocalDirectory\\bin\n\nDefault value is fetched from the current configuration on the machine\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$Script:PackageDirectory\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MetaDataDir\nThe path to the meta data directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: \"$Script:MetaDataDir\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DeleteFolders\nInstruct the cmdlet to delete the model folder\n\nThis is useful when you are trying to clean up the folders in your source control / branch\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: ModelUtil, Axmodel, Model, Remove, Delete, Source Control, Vsts, Azure DevOps\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Remove-D365User.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Remove-D365User\n\n## SYNOPSIS\nDelete an user from the environment\n\n## SYNTAX\n\n```\nRemove-D365User [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>]\n [[-SqlPwd] <String>] [-Email] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\nDeletes the user from the database, including security configuration\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nRemove-D365User -Email \"Claire@contoso.com\"\n```\n\nThis will move all security and user details from the user with the email address\n\"Claire@contoso.com\"\n\n### EXAMPLE 2\n```\nGet-D365User -Email *contoso.com | Remove-D365User\n```\n\nThis will first get all users from the database that matches the *contoso.com\nsearch and pipe their emails to Remove-D365User for it to delete them.\n\n## PARAMETERS\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Email\nThe search string to select which user(s) should be updated.\n\nYou have to specific the explicit email address of the user you want to remove\n\nThe cmdlet will not be able to delete the ADMIN user, this is to prevent you\nfrom being locked out of the system.\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 6\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Rasmus Andersen (@ITRasmus)\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Rename-D365ComputerName.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Rename-D365ComputerName\n\n## SYNOPSIS\nFunction for renaming computer.\nRenames Computer and changes the SSRS Configration\n\n## SYNTAX\n\n```\nRename-D365ComputerName [-NewName] <String> [[-SSRSReportDatabase] <String>] [[-DatabaseServer] <String>]\n [[-DatabaseName] <String>] [[-SqlUser] <String>] [[-SqlPwd] <String>] [[-LogPath] <String>]\n [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nWhen doing development on-prem, there is as need for changing the Computername.\nFunction both changes Computername and SSRS Configuration\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nRename-D365ComputerName -NewName \"Demo-8.1\" -SSRSReportDatabase \"ReportServer\"\n```\n\nThis will rename the local machine to the \"Demo-8.1\" as the new Windows machine name.\nIt will update the registration inside the SQL Server Reporting Services configuration to handle the new name of the machine.\n\n## PARAMETERS\n\n### -NewName\nThe new name for the computer\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SSRSReportDatabase\nName of the SSRS reporting database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: DynamicsAxReportServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -LogPath\nThe path where the log file(s) will be saved\n\nWhen running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: LogDir\n\nRequired: False\nPosition: 7\nDefault value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\RsConfig\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputCommandOnly\nInstruct the cmdlet to only output the command that you would have to execute by hand\n\nWill include full path to the executable and the needed parameters based on your selection\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Rasmus Andersen (@ITRasmus)\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Rename-D365Instance.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Rename-D365Instance\n\n## SYNOPSIS\nRename as D365FO Demo/Dev box\n\n## SYNTAX\n\n```\nRename-D365Instance [-NewName] <String> [[-AosServiceWebRootPath] <String>]\n [[-IISServerApplicationHostConfigFile] <String>] [[-HostsFile] <String>] [[-BackupExtension] <String>]\n [[-MRConfigFile] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nThe Rename function, changes the config values used by a D365FO dev box for identifying its name.\nStandard it is called 'usnconeboxax1aos'\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nRename-D365Instance -NewName \"Demo1\"\n```\n\nThis will rename the D365 for Finance & Operations instance to \"Demo1\".\nThis IIS will be restarted while doing it.\n\n## PARAMETERS\n\n### -NewName\nThe new name wanted for the D365FO instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AosServiceWebRootPath\nPath to the webroot folder for the AOS service 'Default value : C:\\AOSService\\Webroot\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:AOSPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -IISServerApplicationHostConfigFile\nPath to the IISService Application host file, \\[Where the binding configurations is stored\\] 'Default value : C:\\Windows\\System32\\inetsrv\\Config\\applicationHost.config'\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:IISHostFile\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -HostsFile\nPlace of the host file on the current system \\[Local DNS record\\] ' Default value C:\\Windows\\System32\\drivers\\etc\\hosts'\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:Hosts\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BackupExtension\nBackup name for all the files that are changed\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: Bak\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MRConfigFile\nPath to the Financial Reporter (Management Reporter) configuration file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:MRConfigFile\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Rasmus Andersen (@ITRasmus)\nAuthor: Mötz Jensen (@Splaxi)\n\nThe function restarts the IIS Service.\nElevated privileges are required.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Repair-D365BacpacModelFile.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Repair-D365BacpacModelFile\n\n## SYNOPSIS\nRepair a bacpac model file\n\n## SYNTAX\n\n```\nRepair-D365BacpacModelFile [-Path] <String> [[-OutputPath] <String>] [[-PathRepairSimple] <String>]\n [[-PathRepairQualifier] <String>] [[-PathRepairReplace] <String>] [-KeepFiles] [-Force] [<CommonParameters>]\n```\n\n## DESCRIPTION\nAs the backend of the Azure SQL infrastructure keeps evolving, the bacpac file can contain invalid instructions while we are trying to import into a local SQL Server installation on a Tier1 environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nRepair-D365BacpacModelFile -Path C:\\Temp\\Base.xml -PathRepairSimple '' -PathRepairQualifier '' -PathRepairReplace 'C:\\Temp\\RepairBacpac.Replace.Custom.json'\n```\n\nThis will only process the Replace section, as the other repair paths are empty - indicating to skip them.\nIt will load the instructions from the 'C:\\Temp\\RepairBacpac.Replace.Custom.json' file and run those in the Replace section.\n\n### EXAMPLE 2\n```\nRepair-D365BacpacModelFile -Path C:\\Temp\\Base.xml -KeepFiles -Force\n```\n\nThis will process all repair sections.\nIt will keep the files in the temporary work directory, for the user to analyze the files further.\nIt will Force overwrite the output file, if it exists already.\n\n## PARAMETERS\n\n### -Path\nPath to the bacpac model file that you want to work against\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputPath\nPath to where the repaired model file should be placed\n\nThe default value is going to create a file next to the Path (input) file, with the '-edited' name appended to it\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PathRepairSimple\nPath to the json file, that contains all the instructions to be executed in the \"Simple\" section\n\nThe default json file is part of the module, and can be located with the below command:\nexplorer.exe $(Join-Path -Path $(Split-Path -Path (Get-Module d365fo.tools -ListAvailable)\\[0\\].Path -Parent) -ChildPath \"internal\\misc\")\n- Look for the \"RepairBacpac.Simple.json\" file\n\nOr you can see the latest version, online, inside the github repository: https://github.com/d365collaborative/d365fo.tools/tree/master/d365fo.tools/internal/misc/RepairBacpac.Simple.json\n\nSimple means, that we can remove complex elements, based on some basic logic.\nE.g.\n\n{\n\"Search\": \"*\\<Element Type=\\\"SqlPermissionStatement\\\"*ms_db_configreader*\",\n\"End\": \"*\\</Element\\>*\"\n}\n\n\"*\\<Element Type=\\\"SqlPermissionStatement\\\"*ms_db_configreader*\" can identify below, and together with \"*\\</Element\\>*\" - we know when to stop.\n\n\\<Element Type=\"SqlPermissionStatement\" Name=\"\\[Grant.Delete.Object\\].\\[ms_db_configreader\\].\\[dbo\\].\\[dbo\\].\\[AutotuneBase\\]\"\\>\n\\<Property Name=\"Permission\" Value=\"4\" /\\>\n\\<Relationship Name=\"Grantee\"\\>\n\\<Entry\\>\n\\<References Name=\"\\[ms_db_configreader\\]\" /\\>\n\\</Entry\\>\n\\</Relationship\\>\n\\<Relationship Name=\"Grantor\"\\>\n\\<Entry\\>\n\\<References ExternalSource=\"BuiltIns\" Name=\"\\[dbo\\]\" /\\>\n\\</Entry\\>\n\\</Relationship\\>\n\\<Relationship Name=\"SecuredObject\"\\>\n\\<Entry\\>\n\\<References Name=\"\\[dbo\\].\\[AutotuneBase\\]\" /\\>\n\\</Entry\\>\n\\</Relationship\\>\n\\</Element\\>\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: \"$script:ModuleRoot\\internal\\misc\\RepairBacpac.Simple.json\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PathRepairQualifier\nPath to the json file, that contains all the instructions to be executed in the \"Qualifier\" section\n\nThe default json file is part of the module, and can be located with the below command:\nexplorer.exe $(Join-Path -Path $(Split-Path -Path (Get-Module d365fo.tools -ListAvailable)\\[0\\].Path -Parent) -ChildPath \"internal\\misc\")\n- Look for the \"RepairBacpac.Qualifier.json\" file\n\nOr you can see the latest version, online, inside the github repository: https://github.com/d365collaborative/d365fo.tools/tree/master/d365fo.tools/internal/misc/RepairBacpac.Qualifier.json\n\nQualifier means, that we can remove complex elements, based on some basic logic.\nE.g.\n\n{\n\"Search\": \"*\\<Element Type=\\\"SqlRoleMembership\\\"\\>*\",\n\"Qualifier\": \"*\\<References Name=*ms_db_configwriter*\",\n\"End\": \"*\\</Element\\>*\"\n}\n\n\"*\\<Element Type=\\\"SqlRoleMembership\\\"\\>*\" can identify below, \"*\\<References Name=*ms_db_configwriter*\" qualifies that we are locating the correct one and together with \"*\\</Element\\>*\" - we know when to stop.\n\n\\<Element Type=\"SqlRoleMembership\"\\>\n\\<Relationship Name=\"Member\"\\>\n\\<Entry\\>\n\\<References Name=\"\\[ms_db_configwriter\\]\" /\\>\n\\</Entry\\>\n\\</Relationship\\>\n\\<Relationship Name=\"Role\"\\>\n\\<Entry\\>\n\\<References ExternalSource=\"BuiltIns\" Name=\"\\[db_ddladmin\\]\" /\\>\n\\</Entry\\>\n\\</Relationship\\>\n\\</Element\\>\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: \"$script:ModuleRoot\\internal\\misc\\RepairBacpac.Qualifier.json\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -PathRepairReplace\nPath to the json file, that contains all the instructions to be executed in the \"Replace\" section\n\nThe default json file is part of the module, and can be located with the below command:\nexplorer.exe $(Join-Path -Path $(Split-Path -Path (Get-Module d365fo.tools -ListAvailable)\\[0\\].Path -Parent) -ChildPath \"internal\\misc\")\n- Look for the \"RepairBacpac.Replace.json\" file\n\nOr you can see the latest version, online, inside the github repository: https://github.com/d365collaborative/d365fo.tools/tree/master/d365fo.tools/internal/misc/RepairBacpac.Replace.json\n\nReplace means, that we can replace/remove strings, based on some basic logic.\nE.g.\n\n{\n\"Search\": \"\\<Property Name=\\\"AutoDrop\\\" Value=\\\"True\\\" /\\>\",\n\"Replace\": \"\"\n}\n\n\"\\<Property Name=\\\"AutoDrop\\\" Value=\\\"True\\\" /\\>\" can identify below, and \"\" is the value we want to replace with it.\n\n\\<Property Name=\"AutoDrop\" Value=\"True\" /\\>\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: \"$script:ModuleRoot\\internal\\misc\\RepairBacpac.Replace.json\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -KeepFiles\nInstruct the cmdlet to keep the files from the repair process\n\nThe files are very large, so only use this as a way to analyze why your model file didn't end up in the desired state\n\nUse it while you evolve/develop your instructions, but remove it from ANY full automation scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nInstruct the cmdlet to overwrite the file specified in the OutputPath if it already exists\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\nAuthor: Florian Hopfner (@FH-Inway)\n\nJson files has to be an array directly in the root of the file.\nAll \" (double quotes) has to be escaped with \\\" - otherwise it will not work as intended.\n\nThis cmdlet is inspired by the work of \"Brad Bateman\" (github: @batetech)\n\nHis github profile can be found here:\nhttps://github.com/batetech\n\nFlorian Hopfner did a gist implementation, which has been used as the foundation for this implementation\n\nThe original gist is: https://gist.github.com/FH-Inway/f485c720b43b72bffaca5fb6c094707e\n\nHis github profile can be found here:\nhttps://github.com/FH-Inway\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Restart-D365Environment.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Restart-D365Environment\n\n## SYNOPSIS\nRestart the different services\n\n## SYNTAX\n\n### Default (Default)\n```\nRestart-D365Environment [[-ComputerName] <String[]>] [-All] [-Kill] [-ShowOriginalProgress]\n [<CommonParameters>]\n```\n\n### Specific\n```\nRestart-D365Environment [[-ComputerName] <String[]>] [-Aos] [-Batch] [-FinancialReporter] [-DMF] [-Kill]\n [-ShowOriginalProgress] [<CommonParameters>]\n```\n\n## DESCRIPTION\nRestart the different services in a Dynamics 365 Finance & Operations environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nRestart-D365Environment -All\n```\n\nThis will stop all services and then start all services again.\n\n### EXAMPLE 2\n```\nRestart-D365Environment -All -ShowOriginalProgress\n```\n\nThis will stop all services and then start all services again.\nThe progress of Stopping the different services will be written to the console / host.\nThe progress of Starting the different services will be written to the console / host.\n\n### EXAMPLE 3\n```\nRestart-D365Environment -ComputerName \"TEST-SB-AOS1\",\"TEST-SB-AOS2\",\"TEST-SB-BI1\" -All\n```\n\nThis will work against the machines: \"TEST-SB-AOS1\",\"TEST-SB-AOS2\",\"TEST-SB-BI1\".\nThis will stop all services and then start all services again.\n\n### EXAMPLE 4\n```\nRestart-D365Environment -Aos -Batch\n```\n\nThis will stop the AOS and Batch services and then start the AOS and Batch services again.\n\n### EXAMPLE 5\n```\nRestart-D365Environment -FinancialReporter -DMF\n```\n\nThis will stop the FinancialReporter and DMF services and then start the FinancialReporter and DMF services again.\n\n### EXAMPLE 6\n```\nRestart-D365Environment -All -Kill\n```\n\nThis will stop all services and then start all services again.\nIt will use the Kill parameter to make sure that the services is stopped.\n\n## PARAMETERS\n\n### -ComputerName\nAn array of computers that you want to work against\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: @($env:computername)\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -All\nInstructs the cmdlet work against all relevant services\n\nIncludes:\nAos\nBatch\nFinancial Reporter\nDMF\n\n```yaml\nType: SwitchParameter\nParameter Sets: Default\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: True\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Aos\nInstructs the cmdlet to work against the AOS (IIS) service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Batch\nInstructs the cmdlet to work against the Batch service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FinancialReporter\nInstructs the cmdlet to work against the Financial Reporter (Management Reporter 2012)\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DMF\nInstructs the cmdlet to work against the DMF service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Kill\nInstructs the cmdlet to kill the service(s) that you want to restart\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Environment, Service, Services, Aos, Batch, Servicing\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Restore-D365DevConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Restore-D365DevConfig\n\n## SYNOPSIS\nRestore the DynamicsDevConfig.xml file\n\n## SYNTAX\n\n```\nRestore-D365DevConfig [[-Path] <String>] [-Force] [<CommonParameters>]\n```\n\n## DESCRIPTION\nWill restore the DynamicsDevConfig.xml file located in the PackagesLocalDirectory\\Bin folder\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nRestore-D365DevConfig -Force\n```\n\nWill restore the DynamicsDevConfig.xml file, and overwrite the current DynamicsDevConfig.xml file in the PackagesLocalDirectory\\Bin folder.\nIt will use the default path \"C:\\Temp\\d365fo.tools\\DevConfigBackup\" as the source directory.\nIt will overwrite the current DynamicsDevConfig.xml file.\n\nA result set example:\n\nFilename              LastModified         File\n--------              ------------         ----\nDynamicsDevConfig.xml 6/29/2021 7:31:04 PM K:\\AosService\\PackagesLocalDirectory\\Bin\\DynamicsDevConfig.xml\n\n## PARAMETERS\n\n### -Path\nPath to the folder where you the desired DynamicsDevConfig.xml file that you want restored is located\n\nDefault is: \"C:\\Temp\\d365fo.tools\\DevConfigBackup\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $(Join-Path $Script:DefaultTempPath \"DevConfigBackup\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nInstructs the cmdlet to overwrite the destination file if it already exists\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Web Server, IIS, IIS Express, Development\n\nAuthor: Sander Holvoet (@smholvoet)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Restore-D365WebConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Restore-D365WebConfig\n\n## SYNOPSIS\nRestore the web.config file\n\n## SYNTAX\n\n```\nRestore-D365WebConfig [[-Path] <String>] [-Force] [<CommonParameters>]\n```\n\n## DESCRIPTION\nWill restore the web.config file located back into the AOS / IIS folder\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nRestore-D365WebConfig -Force\n```\n\nWill restore the web.config file, and overwrite the current web.config file in the AOS / IIS folder.\nIt will use the default path \"C:\\Temp\\d365fo.tools\\WebConfigBackup\" as the source directory.\nIt will overwrite the current web.config file.\n\nA result set example:\n\nFilename   LastModified         File\n--------   ------------         ----\nweb.config 6/29/2021 7:31:04 PM K:\\AosService\\WebRoot\\web.config\n\n## PARAMETERS\n\n### -Path\nPath to the folder where you the desired web.config file that you want restored is located\n\nDefault is: \"C:\\Temp\\d365fo.tools\\WebConfigBackup\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $(Join-Path $Script:DefaultTempPath \"WebConfigBackup\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nInstructs the cmdlet to overwrite the destination file if it already exists\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: DEV, Tier2, DB, Database, Debug, JIT, LCS, Azure DB\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Send-D365BroadcastMessage.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Send-D365BroadcastMessage\n\n## SYNOPSIS\nSend broadcast message to online users in D365FO\n\n## SYNTAX\n\n```\nSend-D365BroadcastMessage [[-Tenant] <String>] [[-URL] <String>] [[-ClientId] <String>]\n [[-ClientSecret] <String>] [[-TimeZone] <String>] [[-StartTime] <DateTime>] [[-EndingInMinutes] <Int32>]\n [-OnPremise] [<CommonParameters>]\n```\n\n## DESCRIPTION\nUtilize the same messaging framework available from LCS and send a broadcast message to all online users in the environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSend-D365BroadcastMessage\n```\n\nThis will send a message to all active users that are working on default D365FO environment.\n\nSee the RELATED LINKS section for the supporting cmdlets needed to store a default configuration.\n\n### EXAMPLE 2\n```\nSend-D365BroadcastMessage -Tenant \"e674da86-7ee5-40a7-b777-1111111111111\" -URL \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" -ClientId \"dea8d7a9-1602-4429-b138-111111111111\" -ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\"\n```\n\nThis will send a message to all active users that are working on the D365FO environment located at \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\".\nIt will authenticate against the Azure Active Directory with the \"e674da86-7ee5-40a7-b777-1111111111111\" guid.\nIt will use the ClientId \"dea8d7a9-1602-4429-b138-111111111111\" and ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\" go get access to the environment.\nIt will use the default value \"UTC\" Time Zone for converting the different time and dates.\nIt will use the default start time which is NOW.\nIt will use the default end time which is 60 minutes.\n\n### EXAMPLE 3\n```\nSend-D365BroadcastMessage -OnPremise -Tenant \"https://adfs.local/adfs\" -URL \"https://ax-sandbox.d365fo.local\" -ClientId \"dea8d7a9-1602-4429-b138-111111111111\" -ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\"\n```\n\nThis will send a message to all active users that are working on the D365FO OnPremise environment located at \"https://ax-sandbox.d365fo.local\".\nIt will authenticate against Local ADFS with the \"https://adfs.local/adfs\" path\nIt will use the ClientId \"dea8d7a9-1602-4429-b138-111111111111\" and ClientSecret \"Vja/VmdxaLOPR+alkjfsadffelkjlfw234522\" go get access to the environment.\nIt will use the default value \"UTC\" Time Zone for converting the different time and dates.\nIt will use the default start time which is NOW.\nIt will use the default end time which is 60 minutes.\n\n## PARAMETERS\n\n### -Tenant\nAzure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to send a message to\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: $AADGuid\n\nRequired: False\nPosition: 2\nDefault value: $Script:BroadcastTenant\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -URL\nURL / URI for the D365FO environment you want to send a message to\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: URI\n\nRequired: False\nPosition: 3\nDefault value: $Script:BroadcastUrl\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ClientId\nThe ClientId obtained from the Azure Portal when you created a Registered Application\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:BroadcastClientId\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ClientSecret\nThe ClientSecret obtained from the Azure Portal when you created a Registered Application\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:BroadcastClientSecret\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -TimeZone\nId of the Time Zone your environment is running in\n\nYou might experience that the local VM running the D365FO is running another Time Zone than the computer you are running this cmdlet from\n\nAll available .NET Time Zones can be traversed with tab for this parameter\n\nThe default value is \"UTC\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:BroadcastTimeZone\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -StartTime\nThe time and date you want the message to be displayed for the users\n\nDefault value is NOW\n\nThe specified StartTime will always be based on local Time Zone.\nIf you specify a different Time Zone than the local computer is running, the start and end time will be calculated based on your selection.\n\n```yaml\nType: DateTime\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: (Get-Date)\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EndingInMinutes\nSpecify how many minutes into the future you want this message / maintenance window to last\n\nDefault value is 60 minutes\n\nThe specified StartTime will always be based on local Time Zone.\nIf you specify a different Time Zone than the local computer is running, the start and end time will be calculated based on your selection.\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 8\nDefault value: $Script:BroadcastEndingInMinutes\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OnPremise\nSpecify if environnement is an D365 OnPremise\n\nDefault value is \"Not set\" (= Cloud Environnement)\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 9\nDefault value: $Script:BroadcastOnPremise\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nThe specified StartTime will always be based on local Time Zone.\nIf you specify a different Time Zone than the local computer is running, the start and end time will be calculated based on your selection.\n\nFor OnPremise environnement use -OnPremise flag to added \"namespaces/AXSF\" path to D365 URL and allow to get token from local ADFS server\n\nTags: Servicing, Message, Users, Environment\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Add-D365BroadcastMessageConfig]()\n\n[Clear-D365ActiveBroadcastMessageConfig]()\n\n[Get-D365ActiveBroadcastMessageConfig]()\n\n[Get-D365BroadcastMessageConfig]()\n\n[Remove-D365BroadcastMessageConfig]()\n\n[Set-D365ActiveBroadcastMessageConfig]()\n\n"
  },
  {
    "path": "docs/Set-D365ActiveAzureStorageConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365ActiveAzureStorageConfig\n\n## SYNOPSIS\nSet the active Azure Storage Account configuration\n\n## SYNTAX\n\n```\nSet-D365ActiveAzureStorageConfig [[-Name] <String>] [[-ConfigStorageLocation] <String>] [-Temporary]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nUpdates the current active Azure Storage Account configuration with a new one\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365ActiveAzureStorageConfig -Name \"UAT-Exports\"\n```\n\nThis will import the \"UAT-Exports\" set from the Azure Storage Account configurations.\nIt will update the active Azure Storage Account configuration.\n\n### EXAMPLE 2\n```\nSet-D365ActiveAzureStorageConfig -Name \"UAT-Exports\" -ConfigStorageLocation \"System\"\n```\n\nThis will import the \"UAT-Exports\" set from the Azure Storage Account configurations.\nIt will update the active Azure Storage Account configuration.\nThe data will be stored in the system wide configuration storage, which makes it accessible from all users.\n\n### EXAMPLE 3\n```\nSet-D365ActiveAzureStorageConfig -Name \"UAT-Exports\" -Temporary\n```\n\nThis will import the \"UAT-Exports\" set from the Azure Storage Account configurations.\nIt will update the active Azure Storage Account configuration.\nThe update will only last for the rest of this PowerShell console session.\n\n## PARAMETERS\n\n### -Name\nThe name the Azure Storage Account configuration you want to load into the active Azure Storage Account configuration\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ConfigStorageLocation\nParameter used to instruct where to store the configuration objects\n\nThe default value is \"User\" and this will store all configuration for the active user\n\nValid options are:\n\"User\"\n\"System\"\n\n\"System\" will store the configuration so all users can access the configuration objects\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: User\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Temporary\nInstruct the cmdlet to only temporarily override the persisted settings in the configuration storage\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\nYou will have to run the Initialize-D365Config cmdlet first, before this will be capable of working.\n\nYou will have to run the Add-D365AzureStorageConfig cmdlet at least once, before this will be capable of working.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365ActiveBroadcastMessageConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365ActiveBroadcastMessageConfig\n\n## SYNOPSIS\nSet the active broadcast message configuration\n\n## SYNTAX\n\n```\nSet-D365ActiveBroadcastMessageConfig [-Name] <String> [-Temporary] [<CommonParameters>]\n```\n\n## DESCRIPTION\nUpdates the current active broadcast message configuration with a new one\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365ActiveBroadcastMessageConfig -Name \"UAT\"\n```\n\nThis will set the broadcast message configuration named \"UAT\" as the active configuration.\n\n## PARAMETERS\n\n### -Name\nName of the broadcast message configuration you want to load into the active broadcast message configuration\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Temporary\nInstruct the cmdlet to only temporarily override the persisted settings in the configuration store\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Servicing, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret, OnPremise\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n\n[Add-D365BroadcastMessageConfig]()\n\n[Clear-D365ActiveBroadcastMessageConfig]()\n\n[Get-D365ActiveBroadcastMessageConfig]()\n\n[Get-D365BroadcastMessageConfig]()\n\n[Remove-D365BroadcastMessageConfig]()\n\n[Send-D365BroadcastMessage]()\n\n"
  },
  {
    "path": "docs/Set-D365Admin.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365Admin\n\n## SYNOPSIS\nPowershell implementation of the AdminProvisioning tool\n\n## SYNTAX\n\n```\nSet-D365Admin [-AdminSignInName] <String> [[-DatabaseServer] <String>] [[-DatabaseName] <String>]\n [[-SqlUser] <String>] [[-SqlPwd] <String>] [-EnableException] [<CommonParameters>]\n```\n\n## DESCRIPTION\nCmdlet using the AdminProvisioning tool from D365FO\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365Admin \"claire@contoso.com\"\n```\n\nThis will provision claire@contoso.com as administrator for the environment\n\n## PARAMETERS\n\n### -AdminSignInName\nEmail for the Admin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Email\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN)\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Rasmus Andersen (@ITRasmus)\nAuthor: Mötz Jensen (@Splaxi)\nAuthor: Mark Furrer (@devax_mf)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365AzCopyPath.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365AzCopyPath\n\n## SYNOPSIS\nSet the path for AzCopy.exe\n\n## SYNTAX\n\n```\nSet-D365AzCopyPath [-Path] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\nUpdate the path where the module will be looking for the AzCopy.exe executable\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nInvoke-D365InstallAzCopy -Path \"C:\\temp\\d365fo.tools\\AzCopy\\AzCopy.exe\"\n```\n\nThis will update the path for the AzCopy.exe in the modules configuration\n\n## PARAMETERS\n\n### -Path\nPath to the AzCopy.exe\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365ClickOnceTrustPrompt.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365ClickOnceTrustPrompt\n\n## SYNOPSIS\nSet the ClickOnce needed configuration\n\n## SYNTAX\n\n```\nSet-D365ClickOnceTrustPrompt [<CommonParameters>]\n```\n\n## DESCRIPTION\nCreates the needed registry keys and values for ClickOnce to work on the machine\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365ClickOnceTrustPrompt\n```\n\nThis will create / or update the current ClickOnce configuration.\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365DefaultModelForNewProjects.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365DefaultModelForNewProjects\n\n## SYNOPSIS\nSet the default model used creating new projects in Visual Studio\n\n## SYNTAX\n\n```\nSet-D365DefaultModelForNewProjects [-Module] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\nSet the registered default model that is used across all new projects that are created inside Visual Studio when working with D365FO project types\n\nIt will backup the current \"DynamicsDevConfig.xml\" file, for you to revert the changes if anything should go wrong\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365DefaultModelForNewProjects -Model \"FleetManagement\"\n```\n\nThis will update the current default module registered in the \"DynamicsDevConfig.xml\" file.\nThis file is located in Documents\\Visual Studio Dynamics 365\\ or in Documents\\Visual Studio 2015\\Settings\\ depending on the version.\nIt will backup the current \"DynamicsDevConfig.xml\" file.\nIt will replace the value inside the \"DefaultModelForNewProjects\" tag.\n\n## PARAMETERS\n\n### -Module\nThe name of the module / model that you want to be the default model for all new projects used inside Visual Studio when working with D365FO project types\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: Model\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTag: Model, Models, Development, Default Model, Module, Project\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThe work for this cmdlet / function was inspired by Robin Kretzschmar (@DarkSmile92) blog post about changing the default model.\n\nThe direct link for his blog post is: https://robscode.onl/d365-set-default-model-for-new-projects/\n\nHis main blog can found here: https://robscode.onl/\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365FavoriteBookmark.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365FavoriteBookmark\n\n## SYNOPSIS\nEnable the favorite bar and add an URL\n\n## SYNTAX\n\n### D365FO (Default)\n```\nSet-D365FavoriteBookmark [-URL <String>] [-D365FO] [<CommonParameters>]\n```\n\n### AzureDevOps\n```\nSet-D365FavoriteBookmark [-URL <String>] [-AzureDevOps] [<CommonParameters>]\n```\n\n## DESCRIPTION\nEnable the favorite bar in Edge & Chrome and put in the URL as a favorite/bookmark\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365FavoriteBookmark -Url \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\"\n```\n\nThis will add the \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" to the favorite bar, enable the favorite bar and lock it.\nThis will be interpreted as the using the -D365FO parameter also, because that is the expected behavior.\n\n### EXAMPLE 2\n```\nSet-D365FavoriteBookmark -Url \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" -D365FO\n```\n\nThis will add the \"https://usnconeboxax1aos.cloud.onebox.dynamics.com\" to the favorite bar, enable the favorite bar and lock it.\nThe bookmark will be mapped as the one for the Dynamics 365 Finance & Operations instance.\n\n### EXAMPLE 3\n```\nSet-D365FavoriteBookmark -Url \"https://CUSTOMERNAME.visualstudio.com/\" -AzureDevOps\n```\n\nThis will add the \"https://CUSTOMERNAME.visualstudio.com/\" to the favorite bar, enable the favorite bar and lock it.\nThe bookmark will be mapped as the one for the Azure DevOps instance.\n\n### EXAMPLE 4\n```\nGet-D365Url | Set-D365FavoriteBookmark\n```\n\nThis will get the URL from the environment and add that to the favorite bar, enable the favorite bar and lock it.\nThis will be interpreted as the using the -D365FO parameter also, because that is the expected behavior.\n\n## PARAMETERS\n\n### -URL\nThe URL of the shortcut you want to add to the favorite bar\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -D365FO\nInstruct the cmdlet that you want the populate the D365FO favorite entry based on the URL provided\n\n```yaml\nType: SwitchParameter\nParameter Sets: D365FO\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AzureDevOps\nInstruct the cmdlet that you want the populate the AzureDevOps favorite entry based on the URL provided\n\n```yaml\nType: SwitchParameter\nParameter Sets: AzureDevOps\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365FlightServiceCatalogId.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365FlightServiceCatalogId\n\n## SYNOPSIS\nSet the FlightingServiceCatalogID\n\n## SYNTAX\n\n```\nSet-D365FlightServiceCatalogId [[-FlightServiceCatalogId] <String>] [[-AosServiceWebRootPath] <String>]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nSet the FlightingServiceCatalogID element in the web.config file used by D365FO\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365FlightServiceCatalogId\n```\n\nThis will set the FlightingServiceCatalogID element the web.config to the default value \"12719367\".\n\n## PARAMETERS\n\n### -FlightServiceCatalogId\nFlighting catalog ID to be set\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: 12719367\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AosServiceWebRootPath\nPath to the root folder where to locate the web.config file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:AOSPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Flight, Flighting\n\nAuthor: Frank Hüther(@FrankHuether))\n\nThe DataAccess.FlightingServiceCatalogID element must already exist in the web.config file, which is expected to be the case in newer environments.\nhttps://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages#features-flighted-in-data-management-and-enabling-flighted-features\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365LcsApiConfig.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365LcsApiConfig\n\n## SYNOPSIS\nSet the LCS configuration details\n\n## SYNTAX\n\n```\nSet-D365LcsApiConfig [[-ProjectId] <Int32>] [[-ClientId] <String>] [[-BearerToken] <String>]\n [[-ActiveTokenExpiresOn] <Int64>] [[-RefreshToken] <String>] [[-LcsApiUri] <String>] [-Temporary]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nSet the LCS configuration details and save them into the configuration store\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365LcsApiConfig -ProjectId 123456789 -ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" -BearerToken \"JldjfafLJdfjlfsalfd...\" -ActiveTokenExpiresOn 1556909205 -RefreshToken \"Tsdljfasfe2j32324\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n```\n\nThis will set the LCS API configuration.\nThe ProjectId 123456789 will be saved as the default ProjectId for all cmdlets that will interact with LCS, if they require a ProjectId.\nThe ClientId \"9b4f4503-b970-4ade-abc6-2c086e4c4929\" will be saved as the default ClientId for all cmdlets that will interact with LCS, if they require a ClientId.\nThe BearerToken \"JldjfafLJdfjlfsalfd...\" will be saved as the default BearerToken.\nRemember the BearerToken will expire, so you should fill in the ActiveTokenExpiresOn and RefreshToken parameters also.\nThe ActiveTokenExpiresOn 1556909205 will be saved to assist the module in determine whether the BearerToken is still valid or not.\nThe RefreshToken \"Tsdljfasfe2j32324\" will be saved as the default RefreshToken for all cmdlets that will interact with tokens.\nThe LcsApiUri \"https://lcsapi.lcs.dynamics.com\" will be saved as the default LCS HTTP endpoint for all cmdlets that will interact with LCS.\n\n### EXAMPLE 2\n```\nGet-D365LcsApiToken -Username \"serviceaccount@domain.com\" -Password \"TopSecretPassword\" | Set-D365LcsApiConfig\n```\n\nThis will obtain a valid OAuth 2.0 access token from Azure Active Directory and save the needed details.\nThe Username \"serviceaccount@domain.com\" and Password \"TopSecretPassword\" is used in the OAuth 2.0 Grant Flow, to approved that the application should impersonate like \"serviceaccount@domain.com\".\nThe output object received from Get-D365LcsApiToken is piped directly to Set-D365LcsApiConfig.\nSet-D365LcsApiConfig will save the access_token(BearerToken), refresh_token(RefreshToken) and expires_on(ActiveTokenExpiresOn).\n\nThese values will then be available as default values for all LCS cmdlets across the module.\n\nYou can validate the current default values by calling Get-D365LcsApiConfig.\n\n## PARAMETERS\n\n### -ProjectId\nThe project id for the Dynamics 365 for Finance & Operations project inside LCS\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: 0\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ClientId\nThe Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BearerToken\nThe token you want to use when working against the LCS api\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: AccessToken, access_token\n\nRequired: False\nPosition: 3\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -ActiveTokenExpiresOn\nThe point in time where the current bearer token will expire\n\nThe time is measured in Unix Time, total seconds since 1970-01-01\n\n```yaml\nType: Int64\nParameter Sets: (All)\nAliases: expires_on\n\nRequired: False\nPosition: 4\nDefault value: 0\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -RefreshToken\nThe Refresh Token that you want to use for the authentication process\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: refresh_token\n\nRequired: False\nPosition: 5\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -LcsApiUri\nURI / URL to the LCS API you want to use\n\nThe value depends on where your LCS project is located.\nThere are multiple valid URI's / URL's\n\nValid options:\n\"https://lcsapi.lcs.dynamics.com\"\n\"https://lcsapi.eu.lcs.dynamics.com\"\n\"https://lcsapi.fr.lcs.dynamics.com\"\n\"https://lcsapi.sa.lcs.dynamics.com\"\n\"https://lcsapi.uae.lcs.dynamics.com\"\n\"https://lcsapi.ch.lcs.dynamics.com\"\n\"https://lcsapi.no.lcs.dynamics.com\"\n\"https://lcsapi.lcs.dynamics.cn\"\n\"https://lcsapi.gov.lcs.microsoftdynamics.us\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: resource\n\nRequired: False\nPosition: 6\nDefault value: Https://lcsapi.lcs.dynamics.com\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Temporary\nInstruct the cmdlet to only temporarily override the persisted settings in the configuration storage\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Environment, Url, Config, Configuration, LCS, Upload, ClientId\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365NugetPath.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365NugetPath\n\n## SYNOPSIS\nSet the path for nuget.exe\n\n## SYNTAX\n\n```\nSet-D365NugetPath [-Path] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\nUpdate the path where the module will be looking for the nuget.exe executable\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365NugetPath -Path \"C:\\temp\\d365fo.tools\\nuget\\nuget.exe\"\n```\n\nThis will update the path for the nuget.exe in the modules configuration\n\n## PARAMETERS\n\n### -Path\nPath to the nuget.exe\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365OfflineAuthenticationAdminEmail.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365OfflineAuthenticationAdminEmail\n\n## SYNOPSIS\nSets the offline administrator e-mail\n\n## SYNTAX\n\n```\nSet-D365OfflineAuthenticationAdminEmail [-Email] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\nSets the registered offline administrator in the \"DynamicsDevConfig.xml\" file located in the default Package Directory\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365OfflineAuthenticationAdminEmail -Email \"admin@contoso.com\"\n```\n\nWill update the Offline Administrator E-mail address in the DynamicsDevConfig.xml file with \"admin@contoso.com\"\n\n## PARAMETERS\n\n### -Email\nThe desired email address of the to be offline administrator\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nThis cmdlet is inspired by the work of \"Sheikh Sohail Hussain\" (twitter: @SSohailHussain)\n\nHis blog can be found here:\nhttp://d365technext.blogspot.com\n\nThe specific blog post that we based this cmdlet on can be found here:\nhttp://d365technext.blogspot.com/2018/07/offline-authentication-admin-email.html\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365RsatConfiguration.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365RsatConfiguration\n\n## SYNOPSIS\nSet different RSAT configuration values\n\n## SYNTAX\n\n```\nSet-D365RsatConfiguration [[-LogGenerationEnabled] <Boolean>] [[-VerboseSnapshotsEnabled] <Boolean>]\n [[-AddOperatorFieldsToExcelValidationEnabled] <Boolean>] [[-RSATConfigFilename] <Object>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nUpdate different RSAT configuration values while using the tool\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365RsatConfiguration -LogGenerationEnabled $true\n```\n\nThis will enable the log generation logic of RSAT.\n\n### EXAMPLE 2\n```\nSet-D365RsatConfiguration -VerboseSnapshotsEnabled $true\n```\n\nThis will enable the snapshot generation logic of RSAT.\n\n### EXAMPLE 3\n```\nSet-D365RsatConfiguration -AddOperatorFieldsToExcelValidationEnabled $true\n```\n\nThis will enable the operator generation logic of RSAT.\n\n## PARAMETERS\n\n### -LogGenerationEnabled\nWill set the LogGeneration property\n\n$true will make RSAT start generating logs\n$false will stop RSAT from generating logs\n\n```yaml\nType: Boolean\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -VerboseSnapshotsEnabled\nWill set the VerboseSnapshotsEnabled property\n\n$true will make RSAT start generating snapshots and store related details\n$false will stop RSAT from generating snapshots and store related details\n\n```yaml\nType: Boolean\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -AddOperatorFieldsToExcelValidationEnabled\nWill set the AddOperatorFieldsToExcelValidation property\n\n$true will make RSAT start adding the operation options in the excel parameter file\n$false will stop RSAT from adding the operation options in the excel parameter file\n\n```yaml\nType: Boolean\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -RSATConfigFilename\nSpecifies the file name of the RSAT configuration file.\nDefault is 'Microsoft.Dynamics.RegressionSuite.WpfApp.exe.config'\nIf you are using an older version of RSAT, you might need to change this to 'Microsoft.Dynamics.RegressionSuite.WindowsApp.exe.config'\n\n```yaml\nType: Object\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: Microsoft.Dynamics.RegressionSuite.WpfApp.exe.config\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: RSAT, Testing, Regression Suite Automation Test, Regression, Test, Automation, Configuration\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365RsatTier2Crypto.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365RsatTier2Crypto\n\n## SYNOPSIS\nSet the needed configuration to work on Tier2+ environments\n\n## SYNTAX\n\n```\nSet-D365RsatTier2Crypto [<CommonParameters>]\n```\n\n## DESCRIPTION\nSet the needed registry settings for when you are running RSAT against a Tier2+ environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365RsatTier2Crypto\n```\n\nThis will configure the registry to support RSAT against a Tier2+ environment.\n\n## PARAMETERS\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: RSAT, Testing, Regression Suite Automation Test, Regression, Test, Automation, Configuration\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365SDPCleanUp.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365SDPCleanUp\n\n## SYNOPSIS\nSet the cleanup retention period\n\n## SYNTAX\n\n```\nSet-D365SDPCleanUp [[-NumberOfDays] <Int32>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nSets the configured retention period before updates are deleted\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365SDPCleanUp -NumberOfDays 10\n```\n\nThis will set the retention period to 10 days inside the the registry\n\nThe cmdlet REQUIRES elevated permissions to run, otherwise it will fail\n\n## PARAMETERS\n\n### -NumberOfDays\nNumber of days that deployable software packages should remain on the server\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: 30\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nThis cmdlet is based on the findings from Alex Kwitny (@AlexOnDAX)\n\nSee his blog for more info:\nhttp://www.alexondax.com/2018/04/msdyn365fo-how-to-adjust-your.html\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365SqlPackagePath.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365SqlPackagePath\n\n## SYNOPSIS\nSet the path for SqlPackage.exe\n\n## SYNTAX\n\n```\nSet-D365SqlPackagePath [-Path] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\nUpdate the path where the module will be looking for the SqlPackage.exe executable\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365SqlPackagePath -Path \"C:\\Program Files\\Microsoft SQL Server\\150\\DAC\\bin\\SqlPackage.exe\"\n```\n\nThis will update the path for the SqlPackage.exe in the modules configuration\n\n## PARAMETERS\n\n### -Path\nPath to the SqlPackage.exe\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365StartPage.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365StartPage\n\n## SYNOPSIS\nSets the start page in internet explorer\n\n## SYNTAX\n\n### Default (Default)\n```\nSet-D365StartPage [-Name] <String> [<CommonParameters>]\n```\n\n### Url\n```\nSet-D365StartPage [-Url] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\nFunction for setting the start page in internet explorer\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365StartPage -Name 'Demo1'\n```\n\nThis will update the start page for the current user to \"https://Demo1.cloud.onebox.dynamics.com\"\n\n### EXAMPLE 2\n```\nSet-D365StartPage -URL \"https://uat.sandbox.operations.dynamics.com\"\n```\n\nThis will update the start page for the current user to \"https://uat.sandbox.operations.dynamics.com\"\n\n## PARAMETERS\n\n### -Name\nName of the D365 Instance\n\n```yaml\nType: String\nParameter Sets: Default\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Url\nURL of the D365 for Finance & Operations instance that you want to have as your start page\n\n```yaml\nType: String\nParameter Sets: Url\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Rasmus Andersen (@ITRasmus)\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365SysAdmin.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365SysAdmin\n\n## SYNOPSIS\nSet a user to sysadmin\n\n## SYNTAX\n\n```\nSet-D365SysAdmin [[-User] <String>] [[-DatabaseServer] <String>] [[-DatabaseName] <String>]\n [[-SqlUser] <String>] [[-SqlPwd] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nSet a user to sysadmin inside the SQL Server\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365SysAdmin\n```\n\nThis will configure the local administrator on the machine as a SYSADMIN inside SQL Server\n\nFor this to run you need to be running it from a elevated console\n\n### EXAMPLE 2\n```\nSet-D365SysAdmin -SqlPwd Test123\n```\n\nThis will configure the local administrator on the machine as a SYSADMIN inside SQL Server.\nIt will logon as the default SqlUser but use the provided SqlPwd.\n\nThis can be run from a non-elevated console\n\n## PARAMETERS\n\n### -User\nThe user that you want to make sysadmin\n\nMost be well formatted server\\user or domain\\user.\n\nDefault value is: machinename\\administrator\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: \"$env:computername\\administrator\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365TraceParserFileSize.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365TraceParserFileSize\n\n## SYNOPSIS\nConfigue a new maximum file size for the TraceParser\n\n## SYNTAX\n\n```\nSet-D365TraceParserFileSize [-FileSizeInMB] <String> [[-Path] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nChange the maximum file size that the TraceParser generates\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365TraceParserFileSize -FileSizeInMB 2048\n```\n\nThis will configure the maximum TraceParser file to 2048 MB.\n\n## PARAMETERS\n\n### -FileSizeInMB\nThe maximum size that you want to allow the TraceParser file to grow to\n\nOriginal value inside the configuration is 1024 (MB)\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Path\nThe path to the TraceParser.config file that you want to edit\n\nThe default path is: \"\\AosService\\Webroot\\Services\\TraceParserService\\TraceParserService.config\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: (Join-Path $Script:AOSPath \"Services\\TraceParserService\\TraceParserService.config\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365WebConfigDatabase.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365WebConfigDatabase\n\n## SYNOPSIS\nSet the database connection details\n\n## SYNTAX\n\n```\nSet-D365WebConfigDatabase [-DatabaseServer] <String> [-DatabaseName] <String> [-SqlUser] <String>\n [-SqlPwd] <String> [[-Path] <Object>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nOverwrite the current database connection details directly in the web.config file\n\nUsed when you want to connect a DEV box directly to a Tier2 database, and want to debug something that requires better data than usual\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365WebConfigDatabase -DatabaseServer TestServer.database.windows.net -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\"\n```\n\nWill overwrite Server, Database, Username and Password directly in the web.config file.\nIt will save all details unencrypted.\n\n## PARAMETERS\n\n### -DatabaseServer\nThe name of the database server\n\nObtain when you request JIT (Just-in-Time) access through the LCS portal\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\nObtain when you request JIT (Just-in-Time) access through the LCS portal\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\nObtain when you request JIT (Just-in-Time) access through the LCS portal\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\nObtain when you request JIT (Just-in-Time) access through the LCS portal\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 4\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Path\nPath to the web.config file that you want to update with new SQL connection details\n\nDefault is: \"K:\\AosService\\WebRoot\\web.config\" or what else drive that is recognized by the D365FO components as the service drive\n\n```yaml\nType: Object\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: $(Join-Path -Path $Script:AOSPath -ChildPath $Script:WebConfig)\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: DEV, Tier2, DB, Database, Debug, JIT, LCS, Azure DB\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365WebServerType.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365WebServerType\n\n## SYNOPSIS\nSet the web server type to be used to run the D365FO instance\n\n## SYNTAX\n\n```\nSet-D365WebServerType [-RuntimeHostType] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\nSet the web server which will be used to run D365FO: Either IIS or IIS Express.\nNewly deployed development machines will have this set to IIS Express by default.\n\nIt will backup the current \"DynamicsDevConfig.xml\" file, for you to revert the changes if anything should go wrong.\n\nIt will look for the file located in the default Package Directory.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365WebServerType -RuntimeHostType \"IIS\"\n```\n\nThis will update the current web server type registered in the \"DynamicsDevConfig.xml\" file.\nThis file is located \"K:\\AosService\\PackagesLocalDirectory\\bin\".\nIt will backup the current \"DynamicsDevConfig.xml\" file.\nIt will replace the value inside the \"RuntimeHostType\" tag.\n\n## PARAMETERS\n\n### -RuntimeHostType\nThe type of web server you want to use.\n\nValid options are:\n\"IIS\"\n\"IISExpress\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTag: Web Server, IIS, IIS Express, Development\n\nAuthor: Sander Holvoet (@smholvoet)\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Set-D365WorkstationMode.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Set-D365WorkstationMode\n\n## SYNOPSIS\nSet the Workstation mode\n\n## SYNTAX\n\n```\nSet-D365WorkstationMode [-Enabled] <Boolean> [<CommonParameters>]\n```\n\n## DESCRIPTION\nSet the Workstation mode to enabled or not\n\nIt is used to enable the tool to run on a personal machine and still be able to call Invoke-D365TableBrowser and Invoke-D365SysRunnerClass\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSet-D365WorkstationMode -Enabled $true\n```\n\nThis will enable the Workstation mode.\nYou will have to restart the powershell session when you switch around.\n\n## PARAMETERS\n\n### -Enabled\n$True enables the workstation mode while $false deactivated the workstation mode\n\n```yaml\nType: Boolean\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\nYou will have to run the Initialize-D365Config cmdlet first, before this will be capable of working.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Start-D365Environment.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Start-D365Environment\n\n## SYNOPSIS\nCmdlet to start the different services in a Dynamics 365 Finance & Operations environment\n\n## SYNTAX\n\n### Default (Default)\n```\nStart-D365Environment [[-ComputerName] <String[]>] [-All] [-OnlyStartTypeAutomatic] [-ShowOriginalProgress]\n [<CommonParameters>]\n```\n\n### Specific\n```\nStart-D365Environment [[-ComputerName] <String[]>] [-Aos] [-Batch] [-FinancialReporter] [-DMF]\n [-OnlyStartTypeAutomatic] [-ShowOriginalProgress] [<CommonParameters>]\n```\n\n## DESCRIPTION\nCan start all relevant services that is running in a D365FO environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nStart-D365Environment\n```\n\nThis will run the cmdlet with the default parameters.\nDefault is \"-All\".\nThis will start all D365FO services on the machine.\n\n### EXAMPLE 2\n```\nStart-D365Environment -OnlyStartTypeAutomatic\n```\n\nThis will start all D365FO services on the machine that are configured for Automatic startup.\nIt will exclude all services that are either manual or disabled in their startup configuration.\n\n### EXAMPLE 3\n```\nStart-D365Environment -ShowOriginalProgress\n```\n\nThis will run the cmdlet with the default parameters.\nDefault is \"-All\".\nThis will start all D365FO services on the machine.\nThe progress of starting the different services will be written to the console / host.\n\n### EXAMPLE 4\n```\nStart-D365Environment -All\n```\n\nThis will start all D365FO services on the machine.\n\n### EXAMPLE 5\n```\nStart-D365Environment -Aos -Batch\n```\n\nThis will start the Aos & Batch D365FO services on the machine.\n\n### EXAMPLE 6\n```\nStart-D365Environment -FinancialReporter -DMF\n```\n\nThis will start the FinancialReporter and DMF services on the machine.\n\n## PARAMETERS\n\n### -ComputerName\nAn array of computers that you want to start services on.\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: @($env:computername)\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -All\nSet when you want to start all relevant services\n\nIncludes:\nAos\nBatch\nFinancial Reporter\n\n```yaml\nType: SwitchParameter\nParameter Sets: Default\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: True\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Aos\nStart the Aos (iis) service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Batch\nStart the batch service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FinancialReporter\nStart the financial reporter (Management Reporter 2012) service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DMF\nStart the Data Management Framework service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OnlyStartTypeAutomatic\nInstruct the cmdlet to filter out services that are set to manual start or disabled\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Start-D365EnvironmentV2.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Start-D365EnvironmentV2\n\n## SYNOPSIS\nCmdlet to start the different services in a Dynamics 365 Finance & Operations environment\n\n## SYNTAX\n\n### Default (Default)\n```\nStart-D365EnvironmentV2 [-All] [-OnlyStartTypeAutomatic] [-ShowOriginalProgress] [<CommonParameters>]\n```\n\n### Specific\n```\nStart-D365EnvironmentV2 [-Aos] [-Batch] [-FinancialReporter] [-DMF] [-OnlyStartTypeAutomatic]\n [-ShowOriginalProgress] [<CommonParameters>]\n```\n\n## DESCRIPTION\nCan start all relevant services that is running in a D365FO environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nStart-D365EnvironmentV2\n```\n\nThis will run the cmdlet with the default parameters.\nDefault is \"-All\".\nThis will start all D365FO services on the machine.\n\n### EXAMPLE 2\n```\nStart-D365EnvironmentV2 -OnlyStartTypeAutomatic\n```\n\nThis will start all D365FO services on the machine that are configured for Automatic startup.\nIt will exclude all services that are either manual or disabled in their startup configuration.\n\n### EXAMPLE 3\n```\nStart-D365EnvironmentV2 -ShowOriginalProgress\n```\n\nThis will run the cmdlet with the default parameters.\nDefault is \"-All\".\nThis will start all D365FO services on the machine.\nThe progress of starting the different services will be written to the console / host.\n\n### EXAMPLE 4\n```\nStart-D365EnvironmentV2 -All\n```\n\nThis will start all D365FO services on the machine.\n\n### EXAMPLE 5\n```\nStart-D365EnvironmentV2 -Aos -Batch\n```\n\nThis will start the Aos & Batch D365FO services on the machine.\n\n### EXAMPLE 6\n```\nStart-D365EnvironmentV2 -FinancialReporter -DMF\n```\n\nThis will start the FinancialReporter and DMF services on the machine.\n\n### EXAMPLE 7\n```\nEnable-D365Exception\n```\n\nPS C:\\\\\\> Start-D365EnvironmentV2\n\nThis will run the cmdlet with the default parameters.\nDefault is \"-All\".\nThis will start all D365FO services on the machine.\nIf a service does not start, it will throw an exception.\n\n## PARAMETERS\n\n### -All\nSet when you want to start all relevant services\n\nIncludes:\nAos\nBatch\nFinancial Reporter\nData Management Framework\n\n```yaml\nType: SwitchParameter\nParameter Sets: Default\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: True\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Aos\nStart the Aos (iis) service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Batch\nStart the batch service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FinancialReporter\nStart the financial reporter (Management Reporter 2012) service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DMF\nStart the Data Management Framework service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OnlyStartTypeAutomatic\nInstruct the cmdlet to filter out services that are set to manual start or disabled\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Vincent Verweij (@VincentVerweij)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Start-D365EventTrace.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Start-D365EventTrace\n\n## SYNOPSIS\nStart an Event Trace session\n\n## SYNTAX\n\n```\nStart-D365EventTrace [-ProviderName] <String[]> [[-OutputPath] <String>] [[-SessionName] <String>]\n [[-FileName] <String>] [[-OutputFormat] <String>] [[-MinBuffer] <Int32>] [[-MaxBuffer] <Int32>]\n [[-BufferSizeKB] <Int32>] [[-MaxLogFileSizeMB] <Int32>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nStart an Event Trace session with default values to help you getting started\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nStart-D365EventTrace -ProviderName \"Microsoft-Dynamics-AX-FormServer\",\"Microsoft-Dynamics-AX-XppRuntime\"\n```\n\nThis will start a new Event Tracing session with the binary circular output format.\nIt uses \"Microsoft-Dynamics-AX-FormServer\",\"Microsoft-Dynamics-AX-XppRuntime\" as the providernames.\nIt uses the default output folder \"C:\\Temp\\d365fo.tools\\EventTrace\".\n\nIt will use the default values for the remaining parameters.\n\n### EXAMPLE 2\n```\nStart-D365EventTrace -ProviderName \"Microsoft-Dynamics-AX-FormServer\",\"Microsoft-Dynamics-AX-XppRuntime\" -OutputFormat CSV\n```\n\nThis will start a new Event Tracing session with the comma separated output format.\nIt uses \"Microsoft-Dynamics-AX-FormServer\",\"Microsoft-Dynamics-AX-XppRuntime\" as the providernames.\nIt uses the default output folder \"C:\\Temp\\d365fo.tools\\EventTrace\".\n\nIt will use the default values for the remaining parameters.\n\n## PARAMETERS\n\n### -ProviderName\nName of the provider(s) you want to have part of your trace\n\nAccepts an array/list of provider names\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### -OutputPath\nPath to the output folder where you want to store the ETL file that will be generated\n\nDefault path is \"C:\\Temp\\d365fo.tools\\EventTrace\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: (Join-Path -Path $Script:DefaultTempPath -ChildPath \"EventTrace\")\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SessionName\nName that you want the tracing session to have while running the trace\n\nDefault value is \"d365fo.tools.trace\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: D365fo.tools.trace\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FileName\nName of the file that you want the trace to write its output to\n\nDefault value is \"d365fo.tools.trace.etl\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: D365fo.tools.trace.etl\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputFormat\nThe desired output format of the ETL file being outputted from the tracing session\n\nDefault value is \"bincirc\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: Bincirc\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MinBuffer\nThe minimum buffer size in MB that you want the tracing session to work with\n\nDefault value is 10240\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: 10240\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MaxBuffer\nThe maximum buffer size in MB that you want the tracing session to work with\n\nDefault value is 10240\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: 10240\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -BufferSizeKB\nThe buffer size in KB that you want the tracing session to work with\n\nDefault value is 1024\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 8\nDefault value: 1024\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -MaxLogFileSizeMB\nThe maximum log file size in MB that you want the tracing session to work with\n\nDefault value is 4096\n\n```yaml\nType: Int32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 9\nDefault value: 4096\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: ETL, EventTracing, EventTrace\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThis cmdlet/function was inspired by the work of Michael Stashwick (@D365Stuff)\n\nHe blog is located here: https://www.d365stuff.co/\n\nand the blogpost that pointed us in the right direction is located here: https://www.d365stuff.co/trace-batch-jobs-and-more-via-cmd-logman/\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Stop-D365Environment.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Stop-D365Environment\n\n## SYNOPSIS\nCmdlet to stop the different services in a Dynamics 365 Finance & Operations environment\n\n## SYNTAX\n\n### Default (Default)\n```\nStop-D365Environment [[-ComputerName] <String[]>] [-All] [-Kill] [-ShowOriginalProgress] [<CommonParameters>]\n```\n\n### Specific\n```\nStop-D365Environment [[-ComputerName] <String[]>] [-Aos] [-Batch] [-FinancialReporter] [-DMF] [-Kill]\n [-ShowOriginalProgress] [<CommonParameters>]\n```\n\n## DESCRIPTION\nCan stop all relevant services that is running in a D365FO environment\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nStop-D365Environment\n```\n\nThis will run the cmdlet with the default parameters.\nDefault is \"-All\".\nThis will stop all D365FO services on the machine.\n\n### EXAMPLE 2\n```\nStop-D365Environment -ShowOriginalProgress\n```\n\nThis will run the cmdlet with the default parameters.\nDefault is \"-All\".\nThis will Stop all D365FO services on the machine.\nThe progress of Stopping the different services will be written to the console / host.\n\n### EXAMPLE 3\n```\nStop-D365Environment -All\n```\n\nThis will stop all D365FO services on the machine.\n\n### EXAMPLE 4\n```\nStop-D365Environment -Aos -Batch\n```\n\nThis will stop the Aos & Batch D365FO services on the machine.\n\n### EXAMPLE 5\n```\nStop-D365Environment -FinancialReporter -DMF\n```\n\nThis will stop the FinancialReporter and DMF services on the machine.\n\n### EXAMPLE 6\n```\nStop-D365Environment -All -Kill\n```\n\nThis will stop all D365FO services on the machine.\nIt will use the Kill parameter to make sure that the services is stopped.\n\n## PARAMETERS\n\n### -ComputerName\nAn array of computers that you want to stop services on.\n\n```yaml\nType: String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: @($env:computername)\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -All\nSet when you want to stop all relevant services\n\nIncludes:\nAos\nBatch\nFinancial Reporter\n\n```yaml\nType: SwitchParameter\nParameter Sets: Default\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: True\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Aos\nStop the Aos (iis) service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Batch\nStop the batch service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -FinancialReporter\nStart the financial reporter (Management Reporter 2012) service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: 5\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DMF\nStart the Data Management Framework service\n\n```yaml\nType: SwitchParameter\nParameter Sets: Specific\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Kill\nInstructs the cmdlet to kill the service(s) that you want to stop\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 7\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowOriginalProgress\nInstruct the cmdlet to show the standard output in the console\n\nDefault is $false which will silence the standard output\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 8\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Stop-D365EventTrace.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Stop-D365EventTrace\n\n## SYNOPSIS\nStop an Event Trace session\n\n## SYNTAX\n\n```\nStop-D365EventTrace [[-SessionName] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nStop an Event Trace session that you have started earlier with the d365fo.tools\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nStop-D365EventTrace\n```\n\nThis will stop an Event Trace session.\nIt will use the \"d365fo.tools.trace\" as the SessionName parameter.\n\n## PARAMETERS\n\n### -SessionName\nName of the tracing session that you want to stop\n\nDefault value is \"d365fo.tools.trace\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: D365fo.tools.trace\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: ETL, EventTracing, EventTrace\n\nAuthor: Mötz Jensen (@Splaxi)\n\nThis cmdlet/function was inspired by the work of Michael Stashwick (@D365Stuff)\n\nHe blog is located here: https://www.d365stuff.co/\n\nand the blogpost that pointed us in the right direction is located here: https://www.d365stuff.co/trace-batch-jobs-and-more-via-cmd-logman/\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Switch-D365ActiveDatabase.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Switch-D365ActiveDatabase\n\n## SYNOPSIS\nSwitches the 2 databases.\nThe Old wil be renamed _original\n\n## SYNTAX\n\n```\nSwitch-D365ActiveDatabase [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>]\n [[-SqlPwd] <String>] [-SourceDatabaseName] <String> [[-DestinationSuffix] <String>] [-EnableException]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\nSwitches the 2 databases.\nThe Old wil be renamed _original\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nSwitch-D365ActiveDatabase -SourceDatabaseName \"GoldenConfig\"\n```\n\nThis will switch the default database AXDB out and put \"GoldenConfig\" in its place instead.\nIt will use the default value for DestinationSuffix which is \"_original\".\nThe destination database \"AXDB\" will be renamed to \"AXDB_original\".\nThe GoldenConfig database will be renamed to \"AXDB\".\n\n### EXAMPLE 2\n```\nSwitch-D365ActiveDatabase -SourceDatabaseName \"AXDB_original\" -DestinationSuffix \"_reverted\"\n```\n\nThis will switch the default database AXDB out and put \"AXDB_original\" in its place instead.\nIt will use the \"_reverted\" value for DestinationSuffix parameter.\nThe destination database \"AXDB\" will be renamed to \"AXDB_reverted\".\nThe \"AXDB_original\" database will be renamed to \"AXDB\".\n\nThis is used when you did a switch already and need to switch back to the original database.\n\nThis example assumes that the used the first example to switch in the GoldenConfig database with default parameters.\n\n## PARAMETERS\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: DestinationDatabaseName\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SourceDatabaseName\nThe database that takes the DatabaseName's place\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: NewDatabaseName\n\nRequired: True\nPosition: 5\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DestinationSuffix\nThe suffix that you want to append onto the database that is being switched out (DestinationDatabaseName / DatabaseName)\n\nThe default value is \"_original\" to mimic the official guides from Microsoft\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: _original\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -EnableException\nThis parameters disables user-friendly warnings and enables the throwing of exceptions\nThis is less user friendly, but allows catching exceptions in calling scripts\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\nAuthor: Rasmus Andersen (@ITRasmus)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Test-D365Command.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Test-D365Command\n\n## SYNOPSIS\nValidate or show parameter set details with colored output\n\n## SYNTAX\n\n```\nTest-D365Command [-CommandText] <String> [-Mode] <String> [-SplatInput <Hashtable>] [-ShowSplatStyleV1]\n [-ShowSplatStyleV2] [-IncludeHelp] [<CommonParameters>]\n```\n\n## DESCRIPTION\nAnalyze a function and it's parameters\n\nThe cmdlet / function is capable of validating a string input with function name and parameters\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nTest-D365Command -CommandText 'Import-D365Bacpac -ImportModeTier2 -SqlUser \"sqladmin\" -SqlPwd \"XyzXyz\" -BacpacFile2 \"C:\\temp\\uat.bacpac\"' -Mode \"Validate\" -IncludeHelp\n```\n\nThis will validate all the parameters that have been passed to the Import-D365Bacpac cmdlet.\nAll supplied parameters that matches a parameter will be marked with an asterisk.\nWill print the coloring help.\n\n### EXAMPLE 2\n```\nTest-D365Command -CommandText 'Import-D365Bacpac' -Mode \"ShowParameters\" -IncludeHelp\n```\n\nThis will display all the parameter sets and their individual parameters.\nWill print the coloring help.\n\n### EXAMPLE 3\n```\n$params = @{}\n```\n\nPS C:\\\\\\> $params.DatabaseName = \"SAMPLEVALUE\"\nPS C:\\\\\\> Test-D365Command -CommandText 'Import-D365Bacpac -ImportModeTier2' -SplatInput $params -Mode \"Validate\"\n\nThis builds a hashtable with a property names \"DatabaseName\".\nThe hashtable is passed to the cmdlet to be part of the validation.\n\n## PARAMETERS\n\n### -CommandText\nThe string that you want to analyze\n\nIf there is parameter value present, you have to use the opposite quote strategy to encapsulate the string correctly\n\nE.g.\nfor double quotes\n-CommandText 'Import-D365Bacpac -ImportModeTier2 -SqlUser \"sqladmin\" -SqlPwd \"XyzXyz\" -BacpacFile2 \"C:\\temp\\uat.bacpac\"'\n\nE.g.\nfor single quotes\n-CommandText \"Import-D365Bacpac -ExportModeTier2 -SqlUser 'sqladmin' -SqlPwd 'XyzXyz' -BacpacFile2 'C:\\temp\\uat.bacpac'\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Mode\nThe operation mode of the cmdlet / function\n\nValid options are:\n- Validate\n- ShowParameters\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 3\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SplatInput\nPass in your hashtable that you use for your command execution and have it validated\n\n```yaml\nType: Hashtable\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowSplatStyleV1\nInclude an hashtable splatting for all parameter sets in the output\n\nThe example is built like this:\nPS C:\\\\\\> $params = @{}\nPS C:\\\\\\> $params.PropertyName = \"SAMPLEVALUE\"\nPS C:\\\\\\> Test-FakeCommand @params\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -ShowSplatStyleV2\nInclude an hashtable splatting for all parameter sets in the output\n\nThe example is built like this:\nPS C:\\\\\\> $params = @{\nPS C:\\\\\\> PropertyName = \"SAMPLEVALUE\"\nPS C:\\\\\\> }\nPS C:\\\\\\> Test-FakeCommand @params\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -IncludeHelp\nSwitch to instruct the cmdlet / function to output a simple guide with the colors in it\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Test-D365DataverseConnection.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Test-D365DataverseConnection\n\n## SYNOPSIS\nTest the dataverse connection\n\n## SYNTAX\n\n```\nTest-D365DataverseConnection [[-BinDir] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nInvokes the built-in http communication endpount, that validates the connection between the D365FO environment and dataverse\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nTest-D365DataverseConnection\n```\n\nThis will invoke the http communication component, that validates the basic settings between D365FO and Dataverse.\nIt will output the raw details from the call, to make it easier to troubleshoot the connectivity between D365FO and Dataverse.\n\n## PARAMETERS\n\n### -BinDir\nThe path to the bin directory for the environment\n\nDefault path is the same as the aos service PackagesLocalDirectory\\bin\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: \"$Script:BinDir\\bin\"\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nGeneral notes\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Test-D365EntraIntegration.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Test-D365EntraIntegration\n\n## SYNOPSIS\nTest the Entra Id integration\n\n## SYNTAX\n\n```\nTest-D365EntraIntegration\n```\n\n## DESCRIPTION\nValidates the configuration of the web.config file and the certificate for the environment\n\nIf any of the configuration is missing or in someway incorrect, it will prompt and stating corrective actions needed\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nTest-D365EntraIntegration\n```\n\nThis will validate the settings inside the web.config file.\nIt will search for Aad.Realm, Infrastructure.S2SCertThumbprint, GraphApi.GraphAPIServicePrincipalCert\nIt will search for the certificate that matches the thumbprint.\n\nA result set example:\n\nEntraAppId                           Thumbprint                               Subject    Expiration\n----------                           ----------                               -------    ----------\ne068e004-8bec-48c3-a36f-2ab4982ee738 0768175DF3DFDEA3FA78925ADC1E588707649335 CN=CHEAuth 2/5/2026 8:09:28 AM\n\n## PARAMETERS\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nBased on: https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/dev-tools/secure-developer-vm#external-integrations\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Test-D365FlightServiceCatalogId.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Test-D365FlightServiceCatalogId\n\n## SYNOPSIS\nTest if the FlightingServiceCatalogID is present and filled out\n\n## SYNTAX\n\n```\nTest-D365FlightServiceCatalogId [[-AosServiceWebRootPath] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nTest if the FlightingServiceCatalogID element exists in the web.config file used by D365FO\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nTest-D365FlightServiceCatalogId\n```\n\nThis will open the web.config and check if the FlightingServiceCatalogID element is present or not.\n\n## PARAMETERS\n\n### -AosServiceWebRootPath\nPath to the root folder where to locate the web.config file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:AOSPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Flight, Flighting\n\nAuthor: Mötz Jensen (@Splaxi))\n\nThe DataAccess.FlightingServiceCatalogID must already be set in the web.config file.\nhttps://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entities-data-packages#features-flighted-in-data-management-and-enabling-flighted-features\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Test-D365LabelIdIsValid.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Test-D365LabelIdIsValid\n\n## SYNOPSIS\nChecks if a string is a valid 'Label Id' format\n\n## SYNTAX\n\n```\nTest-D365LabelIdIsValid [-LabelId] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\nThis function will validate if a string is a valid 'Label Id' format.\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nTest-D365LabelIdIsValid -LabelId \"ABC123\"\n```\n\nThis will test the if the LabelId is valid.\nIt will use the \"ABC123\" as the LabelId parameter.\n\nThe expected result is $true\n\n### EXAMPLE 2\n```\nTest-D365LabelIdIsValid -LabelId \"@ABC123\"\n```\n\nThis will test the if the LabelId is valid.\nIt will use the \"@ABC123\" as the LabelId parameter.\n\nThe expected result is $true\n\n### EXAMPLE 3\n```\nTest-D365LabelIdIsValid -LabelId \"@ABC123_1\"\n```\n\nThis will test the if the LabelId is valid.\nIt will use the \"@ABC123_1\" as the LabelId parameter.\n\nThe expected result is $false\n\n### EXAMPLE 4\n```\nTest-D365LabelIdIsValid -LabelId \"ABC.123\" #False\n```\n\nThis will test the if the LabelId is valid.\nIt will use the \"ABC.123\" as the LabelId parameter.\n\nThe expected result is $false\n\n## PARAMETERS\n\n### -LabelId\nThe LabelId string thay you want to validate\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 1\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n### System.Boolean\n## NOTES\nAuthor: Alex Kwitny (@AlexOnDAX)\n\nThe intent of this function is to be used with other methods to create valid labels via scripting.\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Update-D365BacpacModelFileSingleTable.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Update-D365BacpacModelFileSingleTable\n\n## SYNOPSIS\nUpdate the \"model.xml\" from the bacpac file to a single table\n\n## SYNTAX\n\n```\nUpdate-D365BacpacModelFileSingleTable [[-Path] <String>] [-Table] <String> [[-Schema] <String>]\n [[-OutputPath] <String>] [-Force] [<CommonParameters>]\n```\n\n## DESCRIPTION\nUpdate the \"model.xml\" file from inside the bacpac file to only handle a single table\n\nThis can be used to restore a single table as fast as possible to a new data\n\nThe table will be created like ordinary bacpac restore, expect it will only have the raw table definition and indexes, all other objects are dropped\n\nThe output can be used directly with the Import-D365Bacpac cmdlet and its ModelFile parameter, see the example sections for more details\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nUpdate-D365BacpacModelFileSingleTable -Path \"c:\\temp\\d365fo.tools\\bacpac.model.xml\" -Table \"SalesTable\"\n```\n\nThis will create an updated bacpac.model.xml file with only the SalesTable to be imported.\nIt will read the \"c:\\temp\\d365fo.tools\\bacpac.model.xml\" file.\nIt will use the default \"dbo\" as the Schema parameter.\nIt will use the \"SalesTable\" as the Table parameter.\nIt will use the \"c:\\temp\\d365fo.tools\\dbo.salestable.model.xml\" as the default path for OutputPath parameter.\n\n### EXAMPLE 2\n```\nUpdate-D365BacpacModelFileSingleTable -Path \"c:\\temp\\d365fo.tools\\bacpac.model.xml\" -Table \"CommissionSalesGroup\" -Schema \"AX\"\n```\n\nThis will create an updated bacpac.model.xml file with only the \"CommissionSalesGroup\", from the \"AX\" schema, to be imported.\nIt will read the \"c:\\temp\\d365fo.tools\\bacpac.model.xml\" file.\nIt will use the \"AX\" as the Schema for the table.\nIt will use the \"CommissionSalesGroup\" as the Table parameter.\nIt will use the \"c:\\temp\\d365fo.tools\\ax.CommissionSalesGroup.model.xml\" as the default path for OutputPath parameter.\n\n### EXAMPLE 3\n```\nUpdate-D365BacpacModelFileSingleTable -Path \"c:\\temp\\d365fo.tools\\bacpac.model.xml\" -Table \"SalesTable\" -OutputPath \"c:\\temp\\troubleshoot.xml\"\n```\n\nThis will create an updated bacpac.model.xml file with only the SalesTable to be imported.\nIt will read the \"c:\\temp\\d365fo.tools\\bacpac.model.xml\" file.\nIt will use the default \"dbo\" as the Schema parameter.\nIt will use the \"SalesTable\" as the Table parameter.\nIt will use the \"c:\\temp\\troubleshoot.xml\" as the path for OutputPath parameter.\n\n### EXAMPLE 4\n```\nExport-D365BacpacModelFile -Path \"c:\\Temp\\AxDB.bacpac\" | Update-D365BacpacModelFileSingleTable -Table SalesTable\n```\n\nThis will create an updated bacpac.model.xml file with only the SalesTable to be imported.\nIt will read the bacpac model file generated from the Export-D365BacpacModelFile cmdlet.\nIt will use the default \"dbo\" as the Schema parameter.\nIt will use the \"SalesTable\" as the Table parameter.\nIt will use the \"c:\\temp\\d365fo.tools\\dbo.salestable.model.xml\" as the default path for OutputPath parameter.\n\n### EXAMPLE 5\n```\nUpdate-D365BacpacModelFileSingleTable -Path \"c:\\temp\\d365fo.tools\\bacpac.model.xml\" -Table \"SalesTable\" -Force\n```\n\nThis will create an updated bacpac.model.xml file with only the SalesTable to be imported.\nIt will read the \"c:\\temp\\d365fo.tools\\bacpac.model.xml\" file.\nIt will use the default \"dbo\" as the Schema parameter.\nIt will use the \"SalesTable\" as the Table parameter.\nIt will use the \"c:\\temp\\d365fo.tools\\dbo.salestable.model.xml\" as the default path for OutputPath parameter.\n\nIt will overwrite the \"c:\\temp\\d365fo.tools\\dbo.salestable.model.xml\" if it already exists.\n\n## PARAMETERS\n\n### -Path\nPath to the bacpac file that you want to work against\n\nIt can also be a zip file\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases: File, ModelFile\n\nRequired: False\nPosition: 1\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### -Table\nName of the table that you want to be kept inside the model file when the update is done\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 2\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Schema\nSchema where the table that you want to work against exists\n\nThe default value is \"dbo\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: Dbo\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -OutputPath\nPath to where you want the updated bacpac model file to be saved\n\nDefault value is: \"c:\\temp\\d365fo.tools\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DefaultTempPath\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Force\nSwitch to instruct the cmdlet to overwrite the bacpac model file specified in the OutputPath\n\n```yaml\nType: SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: False\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nTags: Bacpac, Servicing, Data, SqlPackage, Import, Table, Troubleshooting\n\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "docs/Update-D365User.md",
    "content": "﻿---\nexternal help file: d365fo.tools-help.xml\nModule Name: d365fo.tools\nonline version:\nschema: 2.0.0\n---\n\n# Update-D365User\n\n## SYNOPSIS\nUpdates the user details in the database\n\n## SYNTAX\n\n```\nUpdate-D365User [[-DatabaseServer] <String>] [[-DatabaseName] <String>] [[-SqlUser] <String>]\n [[-SqlPwd] <String>] [-Email] <String> [[-Company] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\nIs capable of updating all the user details inside the UserInfo table to enable a user to sign in\n\n## EXAMPLES\n\n### EXAMPLE 1\n```\nUpdate-D365User -Email \"claire@contoso.com\"\n```\n\nThis will search for the user with the e-mail address claire@contoso.com and update it with needed information based on the tenant owner of the environment\n\n### EXAMPLE 2\n```\nUpdate-D365User -Email \"*contoso.com\"\n```\n\nThis will search for all users with an e-mail address containing 'contoso.com' and update them with needed information based on the tenant owner of the environment\n\n## PARAMETERS\n\n### -DatabaseServer\nThe name of the database server\n\nIf on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN).\n\nIf Azure use the full address to the database server, e.g.\nserver.database.windows.net\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 1\nDefault value: $Script:DatabaseServer\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -DatabaseName\nThe name of the database\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 2\nDefault value: $Script:DatabaseName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlUser\nThe login name for the SQL Server instance\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 3\nDefault value: $Script:DatabaseUserName\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -SqlPwd\nThe password for the SQL Server user\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 4\nDefault value: $Script:DatabaseUserPassword\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -Email\nThe search string to select which user(s) should be updated.\n\nThe parameter supports wildcards.\nE.g.\n-Email \"*@contoso.com*\"\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 5\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Company\nThe company the user should start in.\n\n```yaml\nType: String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 6\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\nThis 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).\n\n## INPUTS\n\n## OUTPUTS\n\n## NOTES\nAuthor: Rasmus Andersen (@ITRasmus)\nAuthor: Mötz Jensen (@Splaxi)\n\n## RELATED LINKS\n"
  },
  {
    "path": "install.ps1",
    "content": "﻿<#\n\t.SYNOPSIS\n\t\tInstalls the d365fo.tools Module from github\n\t\t\n\t.DESCRIPTION\n\t\tThis script installs the d365fo.tools Module from github.\n\t\t\n\t\tIt does so by ...\n\t\t- downloading the specified branch as zip to $env:TEMP\n\t\t- Unpacking that zip file to a folder in $env:TEMP\n\t\t- Moving that content to a module folder in either program files (default) or the user profile\n\t\n\t.PARAMETER Branch\n\t\tThe branch to install. Installs master by default.\n\t\tUnknown branches will terminate the script in error.\n\t\n\t.PARAMETER UserMode\n\t\tThe downloaded module will be moved to the user profile, rather than program files.\n\n\t.PARAMETER Force\n\t\tThe install script will overwrite an existing module.\n#>\n[CmdletBinding()]\nParam (\n\t[string]\n\t$Branch = \"master\",\n\t\n\t[switch]\n\t$UserMode,\n\t\n\t[switch]\n\t$Force\n)\n\n#region Configuration for cloning script\n# Name of the module that is being cloned\n$ModuleName = \"d365fo.tools\"\n\n# Base path to the github repository\n$BaseUrl = \"https://github.com/d365collaborative/d365fo.tools\"\n\n# If the module is in a subfolder of the cloned repository, specify relative path here. Empty string to skip.\n$SubFolder = \"d365fo.tools\"\n#endregion Configuration for cloning script\n\n\n#region Parameter Calculation\n$doUserMode = $false\nif ($UserMode) { $doUserMode = $true }\nif ($install_CurrentUser) { $doUserMode = $true }\nif ($Scope -eq 'CurrentUser') { $doUserMode = $true }\nif ($install_Branch) { $Branch = $install_Branch }\n#endregion Parameter Calculation\n\n#region Utility Functions\nfunction Compress-Archive\n{\n\t<#\n\t\t.SYNOPSIS\n\t\t\tCreates an archive, or zipped file, from specified files and folders.\n\n\t\t.DESCRIPTION\n\t\t\tThe Compress-Archive cmdlet creates a zipped (or compressed) archive file from one or more specified files or folders. An archive file allows multiple files to be packaged, and optionally compressed, into a single zipped file for easier distribution and storage. An archive file can be compressed by using the compression algorithm specified by the CompressionLevel parameter.\n\n\t\t\tBecause Compress-Archive relies upon the Microsoft .NET Framework API System.IO.Compression.ZipArchive to compress files, the maximum file size that you can compress by using Compress-Archive is currently 2 GB. This is a limitation of the underlying API.\n\n\t\t.PARAMETER Path\n\t\t\tSpecifies the path or paths to the files that you want to add to the archive zipped file. This parameter can accept wildcard characters. Wildcard characters allow you to add all files in a folder to your zipped archive file. To specify multiple paths, and include files in multiple locations in your output zipped file, use commas to separate the paths.\n\n\t\t.PARAMETER LiteralPath\n\t\t\tSpecifies the path or paths to the files that you want to add to the archive zipped file. Unlike the Path parameter, the value of LiteralPath is used exactly as it is typed. No characters are interpreted as wildcards. If the path includes escape characters, enclose each escape character in single quotation marks, to instruct Windows PowerShell not to interpret any characters as escape sequences. To specify multiple paths, and include files in multiple locations in your output zipped file, use commas to separate the paths.\n\n\t\t.PARAMETER DestinationPath\n\t\t\tSpecifies the path to the archive output file. This parameter is required. The specified DestinationPath value should include the desired name of the output zipped file; it specifies either the absolute or relative path to the zipped file. If the file name specified in DestinationPath does not have a .zip file name extension, the cmdlet adds a .zip file name extension.\n\n\t\t.PARAMETER CompressionLevel\n\t\t\tSpecifies how much compression to apply when you are creating the archive file. Faster compression requires less time to create the file, but can result in larger file sizes. The acceptable values for this parameter are:\n\n\t\t\t- Fastest. Use the fastest compression method available to decrease processing time; this can result in larger file sizes.\n\t\t\t- NoCompression. Do not compress the source files.\n\t\t\t- Optimal. Processing time is dependent on file size.\n\n\t\t\tIf this parameter is not specified, the command uses the default value, Optimal.\n\n\t\t.PARAMETER Update\n\t\t\tUpdates the specified archive by replacing older versions of files in the archive with newer versions of files that have the same names. You can also add this parameter to add files to an existing archive.\n\n\t\t.PARAMETER Force\n\t\t\t@{Text=}\n\n\t\t.PARAMETER Confirm\n\t\t\tPrompts you for confirmation before running the cmdlet.\n\n\t\t.PARAMETER WhatIf\n\t\t\tShows what would happen if the cmdlet runs. The cmdlet is not run.\n\n\t\t.EXAMPLE\n\t\t\tExample 1: Create an archive file\n\n\t\t\tPS C:\\>Compress-Archive -LiteralPath C:\\Reference\\Draftdoc.docx, C:\\Reference\\Images\\diagram2.vsd -CompressionLevel Optimal -DestinationPath C:\\Archives\\Draft.Zip\n\n\t\t\tThis command creates a new archive file, Draft.zip, by compressing two files, Draftdoc.docx and diagram2.vsd, specified by the LiteralPath parameter. The compression level specified for this operation is Optimal.\n\n\t\t.EXAMPLE\n\t\t\tExample 2: Create an archive with wildcard characters\n\n\t\t\tPS C:\\>Compress-Archive -Path C:\\Reference\\* -CompressionLevel Fastest -DestinationPath C:\\Archives\\Draft\n\n\t\t\tThis command creates a new archive file, Draft.zip, in the C:\\Archives folder. Note that though the file name extension .zip was not added to the value of the DestinationPath parameter, Windows PowerShell appends this to the specified archive file name automatically. The new archive file contains every file in the C:\\Reference folder, because a wildcard character was used in place of specific file names in the Path parameter. The specified compression level is Fastest, which might result in a larger output file, but compresses a large number of files faster.\n\n\t\t.EXAMPLE\n\t\t\tExample 3: Update an existing archive file\n\n\t\t\tPS C:\\>Compress-Archive -Path C:\\Reference\\* -Update -DestinationPath C:\\Archives\\Draft.Zip\n\n\t\t\tThis command updates an existing archive file, Draft.Zip, in the C:\\Archives folder. The command is run to update Draft.Zip with newer versions of existing files that came from the C:\\Reference folder, and also to add new files that have been added to C:\\Reference since Draft.Zip was initially created.\n\n\t\t.EXAMPLE\n\t\t\tExample 4: Create an archive from an entire folder\n\n\t\t\tPS C:\\>Compress-Archive -Path C:\\Reference -DestinationPath C:\\Archives\\Draft\n\n\t\t\tThis command creates an archive from an entire folder, C:\\Reference. Note that though the file name extension .zip was not added to the value of the DestinationPath parameter, Windows PowerShell appends this to the specified archive file name automatically.\n\t#>\n\t[CmdletBinding(DefaultParameterSetName = \"Path\", SupportsShouldProcess = $true, HelpUri = \"http://go.microsoft.com/fwlink/?LinkID=393252\")]\n\tparam\n\t(\n\t\t[parameter (mandatory = $true, Position = 0, ParameterSetName = \"Path\", ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]\n\t\t[parameter (mandatory = $true, Position = 0, ParameterSetName = \"PathWithForce\", ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]\n\t\t[parameter (mandatory = $true, Position = 0, ParameterSetName = \"PathWithUpdate\", ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]\n\t\t[ValidateNotNullOrEmpty()]\n\t\t[string[]]\n\t\t$Path,\n\n\t\t[parameter (mandatory = $true, ParameterSetName = \"LiteralPath\", ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]\n\t\t[parameter (mandatory = $true, ParameterSetName = \"LiteralPathWithForce\", ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]\n\t\t[parameter (mandatory = $true, ParameterSetName = \"LiteralPathWithUpdate\", ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]\n\t\t[ValidateNotNullOrEmpty()]\n\t\t[Alias(\"PSPath\")]\n\t\t[string[]]\n\t\t$LiteralPath,\n\n\t\t[parameter (mandatory = $true,\n\t\t\t\t\tPosition = 1,\n\t\t\t\t\tValueFromPipeline = $false,\n\t\t\t\t\tValueFromPipelineByPropertyName = $false)]\n\t\t[ValidateNotNullOrEmpty()]\n\t\t[string]\n\t\t$DestinationPath,\n\n\t\t[parameter (\n\t\t\t\t\tmandatory = $false,\n\t\t\t\t\tValueFromPipeline = $false,\n\t\t\t\t\tValueFromPipelineByPropertyName = $false)]\n\t\t[ValidateSet(\"Optimal\", \"NoCompression\", \"Fastest\")]\n\t\t[string]\n\t\t$CompressionLevel = \"Optimal\",\n\n\t\t[parameter(mandatory = $true, ParameterSetName = \"PathWithUpdate\", ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $false)]\n\t\t[parameter(mandatory = $true, ParameterSetName = \"LiteralPathWithUpdate\", ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $false)]\n\t\t[switch]\n\t\t$Update = $false,\n\n\t\t[parameter(mandatory = $true, ParameterSetName = \"PathWithForce\", ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $false)]\n\t\t[parameter(mandatory = $true, ParameterSetName = \"LiteralPathWithForce\", ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $false)]\n\t\t[switch]\n\t\t$Force = $false\n\t)\n\n\tBEGIN\n\t{\n\t\tAdd-Type -AssemblyName System.IO.Compression -ErrorAction Ignore\n\t\tAdd-Type -AssemblyName System.IO.Compression.FileSystem -ErrorAction Ignore\n\n\t\t$zipFileExtension = \".zip\"\n\n\t\t$LocalizedData = ConvertFrom-StringData @'\nPathNotFoundError=The path '{0}' either does not exist or is not a valid file system path.\nExpandArchiveInValidDestinationPath=The path '{0}' is not a valid file system directory path.\nInvalidZipFileExtensionError={0} is not a supported archive file format. {1} is the only supported archive file format.\nArchiveFileIsReadOnly=The attributes of the archive file {0} is set to 'ReadOnly' hence it cannot be updated. If you intend to update the existing archive file, remove the 'ReadOnly' attribute on the archive file else use -Force parameter to override and create a new archive file.\nZipFileExistError=The archive file {0} already exists. Use the -Update parameter to update the existing archive file or use the -Force parameter to overwrite the existing archive file.\nDuplicatePathFoundError=The input to {0} parameter contains a duplicate path '{1}'. Provide a unique set of paths as input to {2} parameter.\nArchiveFileIsEmpty=The archive file {0} is empty.\nCompressProgressBarText=The archive file '{0}' creation is in progress...\nExpandProgressBarText=The archive file '{0}' expansion is in progress...\nAppendArchiveFileExtensionMessage=The archive file path '{0}' supplied to the DestinationPath patameter does not include .zip extension. Hence .zip is appended to the supplied DestinationPath path and the archive file would be created at '{1}'.\nAddItemtoArchiveFile=Adding '{0}'.\nCreateFileAtExpandedPath=Created '{0}'.\nInvalidArchiveFilePathError=The archive file path '{0}' specified as input to the {1} parameter is resolving to multiple file system paths. Provide a unique path to the {2} parameter where the archive file has to be created.\nInvalidExpandedDirPathError=The directory path '{0}' specified as input to the DestinationPath parameter is resolving to multiple file system paths. Provide a unique path to the Destination parameter where the archive file contents have to be expanded.\nFileExistsError=Failed to create file '{0}' while expanding the archive file '{1}' contents as the file '{2}' already exists. Use the -Force parameter if you want to overwrite the existing directory '{3}' contents when expanding the archive file.\nDeleteArchiveFile=The partially created archive file '{0}' is deleted as it is not usable.\nInvalidDestinationPath=The destination path '{0}' does not contain a valid archive file name.\nPreparingToCompressVerboseMessage=Preparing to compress...\nPreparingToExpandVerboseMessage=Preparing to expand...\n'@\n\n\t\t#region Utility Functions\n\t\tfunction GetResolvedPathHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string[]]\n\t\t\t\t$path,\n\n\t\t\t\t[boolean]\n\t\t\t\t$isLiteralPath,\n\n\t\t\t\t[System.Management.Automation.PSCmdlet]\n\t\t\t\t$callerPSCmdlet\n\t\t\t)\n\n\t\t\t$resolvedPaths = @()\n\n\t\t\t# null and empty check are are already done on Path parameter at the cmdlet layer.\n\t\t\tforeach ($currentPath in $path)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tif ($isLiteralPath)\n\t\t\t\t\t{\n\t\t\t\t\t\t$currentResolvedPaths = Resolve-Path -LiteralPath $currentPath -ErrorAction Stop\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t$currentResolvedPaths = Resolve-Path -Path $currentPath -ErrorAction Stop\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t\t$errorMessage = ($LocalizedData.PathNotFoundError -f $currentPath)\n\t\t\t\t\t$exception = New-Object System.InvalidOperationException $errorMessage, $_.Exception\n\t\t\t\t\t$errorRecord = CreateErrorRecordHelper \"ArchiveCmdletPathNotFound\" $null ([System.Management.Automation.ErrorCategory]::InvalidArgument) $exception $currentPath\n\t\t\t\t\t$callerPSCmdlet.ThrowTerminatingError($errorRecord)\n\t\t\t\t}\n\n\t\t\t\tforeach ($currentResolvedPath in $currentResolvedPaths)\n\t\t\t\t{\n\t\t\t\t\t$resolvedPaths += $currentResolvedPath.ProviderPath\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$resolvedPaths\n\t\t}\n\n\t\tfunction Add-CompressionAssemblies\n\t\t{\n\n\t\t\tif ($PSEdition -eq \"Desktop\")\n\t\t\t{\n\t\t\t\tAdd-Type -AssemblyName System.IO.Compression\n\t\t\t\tAdd-Type -AssemblyName System.IO.Compression.FileSystem\n\t\t\t}\n\t\t}\n\n\t\tfunction IsValidFileSystemPath\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string[]]\n\t\t\t\t$path\n\t\t\t)\n\n\t\t\t$result = $true;\n\n\t\t\t# null and empty check are are already done on Path parameter at the cmdlet layer.\n\t\t\tforeach ($currentPath in $path)\n\t\t\t{\n\t\t\t\tif (!([System.IO.File]::Exists($currentPath) -or [System.IO.Directory]::Exists($currentPath)))\n\t\t\t\t{\n\t\t\t\t\t$errorMessage = ($LocalizedData.PathNotFoundError -f $currentPath)\n\t\t\t\t\tThrowTerminatingErrorHelper \"PathNotFound\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $currentPath\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn $result;\n\t\t}\n\n\n\t\tfunction ValidateDuplicateFileSystemPath\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string]\n\t\t\t\t$inputParameter,\n\n\t\t\t\t[string[]]\n\t\t\t\t$path\n\t\t\t)\n\n\t\t\t$uniqueInputPaths = @()\n\n\t\t\t# null and empty check are are already done on Path parameter at the cmdlet layer.\n\t\t\tforeach ($currentPath in $path)\n\t\t\t{\n\t\t\t\t$currentInputPath = $currentPath.ToUpper()\n\t\t\t\tif ($uniqueInputPaths.Contains($currentInputPath))\n\t\t\t\t{\n\t\t\t\t\t$errorMessage = ($LocalizedData.DuplicatePathFoundError -f $inputParameter, $currentPath, $inputParameter)\n\t\t\t\t\tThrowTerminatingErrorHelper \"DuplicatePathFound\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $currentPath\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t$uniqueInputPaths += $currentInputPath\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfunction CompressionLevelMapper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string]\n\t\t\t\t$compressionLevel\n\t\t\t)\n\n\t\t\t$compressionLevelFormat = [System.IO.Compression.CompressionLevel]::Optimal\n\n\t\t\t# CompressionLevel format is already validated at the cmdlet layer.\n\t\t\tswitch ($compressionLevel.ToString())\n\t\t\t{\n\t\t\t\t\"Fastest\"\n\t\t\t\t{\n\t\t\t\t\t$compressionLevelFormat = [System.IO.Compression.CompressionLevel]::Fastest\n\t\t\t\t}\n\t\t\t\t\"NoCompression\"\n\t\t\t\t{\n\t\t\t\t\t$compressionLevelFormat = [System.IO.Compression.CompressionLevel]::NoCompression\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn $compressionLevelFormat\n\t\t}\n\n\t\tfunction CompressArchiveHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string[]]\n\t\t\t\t$sourcePath,\n\n\t\t\t\t[string]\n\t\t\t\t$destinationPath,\n\n\t\t\t\t[string]\n\t\t\t\t$compressionLevel,\n\n\t\t\t\t[bool]\n\t\t\t\t$isUpdateMode\n\t\t\t)\n\n\t\t\t$numberOfItemsArchived = 0\n\t\t\t$sourceFilePaths = @()\n\t\t\t$sourceDirPaths = @()\n\n\t\t\tforeach ($currentPath in $sourcePath)\n\t\t\t{\n\t\t\t\t$result = Test-Path -LiteralPath $currentPath -PathType Leaf\n\t\t\t\tif ($result -eq $true)\n\t\t\t\t{\n\t\t\t\t\t$sourceFilePaths += $currentPath\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t$sourceDirPaths += $currentPath\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t# The Soure Path contains one or more directory (this directory can have files under it) and no files to be compressed.\n\t\t\tif ($sourceFilePaths.Count -eq 0 -and $sourceDirPaths.Count -gt 0)\n\t\t\t{\n\t\t\t\t$currentSegmentWeight = 100/[double]$sourceDirPaths.Count\n\t\t\t\t$previousSegmentWeight = 0\n\t\t\t\tforeach ($currentSourceDirPath in $sourceDirPaths)\n\t\t\t\t{\n\t\t\t\t\t$count = CompressSingleDirHelper $currentSourceDirPath $destinationPath $compressionLevel $true $isUpdateMode $previousSegmentWeight $currentSegmentWeight\n\t\t\t\t\t$numberOfItemsArchived += $count\n\t\t\t\t\t$previousSegmentWeight += $currentSegmentWeight\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t# The Soure Path contains only files to be compressed.\n\t\t\telseIf ($sourceFilePaths.Count -gt 0 -and $sourceDirPaths.Count -eq 0)\n\t\t\t{\n\t\t\t\t# $previousSegmentWeight is equal to 0 as there are no prior segments.\n\t\t\t\t# $currentSegmentWeight is set to 100 as all files have equal weightage.\n\t\t\t\t$previousSegmentWeight = 0\n\t\t\t\t$currentSegmentWeight = 100\n\n\t\t\t\t$numberOfItemsArchived = CompressFilesHelper $sourceFilePaths $destinationPath $compressionLevel $isUpdateMode $previousSegmentWeight $currentSegmentWeight\n\t\t\t}\n\t\t\t# The Soure Path contains one or more files and one or more directories (this directory can have files under it) to be compressed.\n\t\t\telseif ($sourceFilePaths.Count -gt 0 -and $sourceDirPaths.Count -gt 0)\n\t\t\t{\n\t\t\t\t# each directory is considered as an individual segments & all the individual files are clubed in to a separate sgemnet.\n\t\t\t\t$currentSegmentWeight = 100/[double]($sourceDirPaths.Count + 1)\n\t\t\t\t$previousSegmentWeight = 0\n\n\t\t\t\tforeach ($currentSourceDirPath in $sourceDirPaths)\n\t\t\t\t{\n\t\t\t\t\t$count = CompressSingleDirHelper $currentSourceDirPath $destinationPath $compressionLevel $true $isUpdateMode $previousSegmentWeight $currentSegmentWeight\n\t\t\t\t\t$numberOfItemsArchived += $count\n\t\t\t\t\t$previousSegmentWeight += $currentSegmentWeight\n\t\t\t\t}\n\n\t\t\t\t$count = CompressFilesHelper $sourceFilePaths $destinationPath $compressionLevel $isUpdateMode $previousSegmentWeight $currentSegmentWeight\n\t\t\t\t$numberOfItemsArchived += $count\n\t\t\t}\n\n\t\t\treturn $numberOfItemsArchived\n\t\t}\n\n\t\tfunction CompressFilesHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string[]]\n\t\t\t\t$sourceFilePaths,\n\n\t\t\t\t[string]\n\t\t\t\t$destinationPath,\n\n\t\t\t\t[string]\n\t\t\t\t$compressionLevel,\n\n\t\t\t\t[bool]\n\t\t\t\t$isUpdateMode,\n\n\t\t\t\t[double]\n\t\t\t\t$previousSegmentWeight,\n\n\t\t\t\t[double]\n\t\t\t\t$currentSegmentWeight\n\t\t\t)\n\n\t\t\t$numberOfItemsArchived = ZipArchiveHelper $sourceFilePaths $destinationPath $compressionLevel $isUpdateMode $null $previousSegmentWeight $currentSegmentWeight\n\n\t\t\treturn $numberOfItemsArchived\n\t\t}\n\n\t\tfunction CompressSingleDirHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string]\n\t\t\t\t$sourceDirPath,\n\n\t\t\t\t[string]\n\t\t\t\t$destinationPath,\n\n\t\t\t\t[string]\n\t\t\t\t$compressionLevel,\n\n\t\t\t\t[bool]\n\t\t\t\t$useParentDirAsRoot,\n\n\t\t\t\t[bool]\n\t\t\t\t$isUpdateMode,\n\n\t\t\t\t[double]\n\t\t\t\t$previousSegmentWeight,\n\n\t\t\t\t[double]\n\t\t\t\t$currentSegmentWeight\n\t\t\t)\n\n\t\t\t[System.Collections.Generic.List[System.String]]$subDirFiles = @()\n\n\t\t\tif ($useParentDirAsRoot)\n\t\t\t{\n\t\t\t\t$sourceDirInfo = New-Object -TypeName System.IO.DirectoryInfo -ArgumentList $sourceDirPath\n\t\t\t\t$sourceDirFullName = $sourceDirInfo.Parent.FullName\n\n\t\t\t\t# If the directory is present at the drive level the DirectoryInfo.Parent include '\\' example: C:\\\n\t\t\t\t# On the other hand if the directory exists at a deper level then DirectoryInfo.Parent\n\t\t\t\t# has just the path (without an ending '\\'). example C:\\source\n\t\t\t\tif ($sourceDirFullName.Length -eq 3)\n\t\t\t\t{\n\t\t\t\t\t$modifiedSourceDirFullName = $sourceDirFullName\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t$modifiedSourceDirFullName = $sourceDirFullName + \"\\\"\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$sourceDirFullName = $sourceDirPath\n\t\t\t\t$modifiedSourceDirFullName = $sourceDirFullName + \"\\\"\n\t\t\t}\n\n\t\t\t$dirContents = Get-ChildItem -LiteralPath $sourceDirPath -Recurse\n\t\t\tforeach ($currentContent in $dirContents)\n\t\t\t{\n\t\t\t\t$isContainer = $currentContent -is [System.IO.DirectoryInfo]\n\t\t\t\tif (!$isContainer)\n\t\t\t\t{\n\t\t\t\t\t$subDirFiles.Add($currentContent.FullName)\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t# The currentContent points to a directory.\n\t\t\t\t\t# We need to check if the directory is an empty directory, if so such a\n\t\t\t\t\t# directory has to be explictly added to the archive file.\n\t\t\t\t\t# if there are no files in the directory the GetFiles() API returns an empty array.\n\t\t\t\t\t$files = $currentContent.GetFiles()\n\t\t\t\t\tif ($files.Count -eq 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t$subDirFiles.Add($currentContent.FullName + \"\\\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$numberOfItemsArchived = ZipArchiveHelper $subDirFiles.ToArray() $destinationPath $compressionLevel $isUpdateMode $modifiedSourceDirFullName $previousSegmentWeight $currentSegmentWeight\n\n\t\t\treturn $numberOfItemsArchived\n\t\t}\n\n\t\tfunction ZipArchiveHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[System.Collections.Generic.List[System.String]]\n\t\t\t\t$sourcePaths,\n\n\t\t\t\t[string]\n\t\t\t\t$destinationPath,\n\n\t\t\t\t[string]\n\t\t\t\t$compressionLevel,\n\n\t\t\t\t[bool]\n\t\t\t\t$isUpdateMode,\n\n\t\t\t\t[string]\n\t\t\t\t$modifiedSourceDirFullName,\n\n\t\t\t\t[double]\n\t\t\t\t$previousSegmentWeight,\n\n\t\t\t\t[double]\n\t\t\t\t$currentSegmentWeight\n\t\t\t)\n\n\t\t\t$numberOfItemsArchived = 0\n\t\t\t$fileMode = [System.IO.FileMode]::Create\n\t\t\t$result = Test-Path -LiteralPath $DestinationPath -PathType Leaf\n\t\t\tif ($result -eq $true)\n\t\t\t{\n\t\t\t\t$fileMode = [System.IO.FileMode]::Open\n\t\t\t}\n\n\t\t\tAdd-CompressionAssemblies\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\t# At this point we are sure that the archive file has write access.\n\t\t\t\t$archiveFileStreamArgs = @($destinationPath, $fileMode)\n\t\t\t\t$archiveFileStream = New-Object -TypeName System.IO.FileStream -ArgumentList $archiveFileStreamArgs\n\n\t\t\t\t$zipArchiveArgs = @($archiveFileStream, [System.IO.Compression.ZipArchiveMode]::Update, $false)\n\t\t\t\t$zipArchive = New-Object -TypeName System.IO.Compression.ZipArchive -ArgumentList $zipArchiveArgs\n\n\t\t\t\t$currentEntryCount = 0\n\t\t\t\t$progressBarStatus = ($LocalizedData.CompressProgressBarText -f $destinationPath)\n\t\t\t\t$bufferSize = 4kb\n\t\t\t\t$buffer = New-Object Byte[] $bufferSize\n\n\t\t\t\tforeach ($currentFilePath in $sourcePaths)\n\t\t\t\t{\n\t\t\t\t\tif ($modifiedSourceDirFullName -ne $null -and $modifiedSourceDirFullName.Length -gt 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t$index = $currentFilePath.IndexOf($modifiedSourceDirFullName, [System.StringComparison]::OrdinalIgnoreCase)\n\t\t\t\t\t\t$currentFilePathSubString = $currentFilePath.Substring($index, $modifiedSourceDirFullName.Length)\n\t\t\t\t\t\t$relativeFilePath = $currentFilePath.Replace($currentFilePathSubString, \"\").Trim()\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t$relativeFilePath = [System.IO.Path]::GetFileName($currentFilePath)\n\t\t\t\t\t}\n\n\t\t\t\t\t# Update mode is selected.\n\t\t\t\t\t# Check to see if archive file already contains one or more zip files in it.\n\t\t\t\t\tif ($isUpdateMode -eq $true -and $zipArchive.Entries.Count -gt 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t$entryToBeUpdated = $null\n\n\t\t\t\t\t\t# Check if the file already exists in the archive file.\n\t\t\t\t\t\t# If so replace it with new file from the input source.\n\t\t\t\t\t\t# If the file does not exist in the archive file then default to\n\t\t\t\t\t\t# create mode and create the entry in the archive file.\n\n\t\t\t\t\t\tforeach ($currentArchiveEntry in $zipArchive.Entries)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif ($currentArchiveEntry.FullName -eq $relativeFilePath)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$entryToBeUpdated = $currentArchiveEntry\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ($entryToBeUpdated -ne $null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t$addItemtoArchiveFileMessage = ($LocalizedData.AddItemtoArchiveFile -f $currentFilePath)\n\t\t\t\t\t\t\t$entryToBeUpdated.Delete()\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t$compression = CompressionLevelMapper $compressionLevel\n\n\t\t\t\t\t# If a directory needs to be added to an archive file,\n\t\t\t\t\t# by convention the .Net API's expect the path of the diretcory\n\t\t\t\t\t# to end with '\\' to detect the path as an directory.\n\t\t\t\t\tif (!$relativeFilePath.EndsWith(\"\\\", [StringComparison]::OrdinalIgnoreCase))\n\t\t\t\t\t{\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$currentFileStream = [System.IO.File]::Open($currentFilePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t# Failed to access the file. Write a non terminating error to the pipeline\n\t\t\t\t\t\t\t\t# and move on with the remaining files.\n\t\t\t\t\t\t\t\t$exception = $_.Exception\n\t\t\t\t\t\t\t\tif ($null -ne $_.Exception -and\n\t\t\t\t\t\t\t\t\t$null -ne $_.Exception.InnerException)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t$exception = $_.Exception.InnerException\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t$errorRecord = CreateErrorRecordHelper \"CompressArchiveUnauthorizedAccessError\" $null ([System.Management.Automation.ErrorCategory]::PermissionDenied) $exception $currentFilePath\n\t\t\t\t\t\t\t\tWrite-Error -ErrorRecord $errorRecord\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ($null -ne $currentFileStream)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$srcStream = New-Object System.IO.BinaryReader $currentFileStream\n\n\t\t\t\t\t\t\t\t$currentArchiveEntry = $zipArchive.CreateEntry($relativeFilePath, $compression)\n\n\t\t\t\t\t\t\t\t# Updating  the File Creation time so that the same timestamp would be retained after expanding the compressed file.\n\t\t\t\t\t\t\t\t# At this point we are sure that Get-ChildItem would succeed.\n\t\t\t\t\t\t\t\t$currentArchiveEntry.LastWriteTime = (Get-Item -LiteralPath $currentFilePath).LastWriteTime\n\n\t\t\t\t\t\t\t\t$destStream = New-Object System.IO.BinaryWriter $currentArchiveEntry.Open()\n\n\t\t\t\t\t\t\t\twhile ($numberOfBytesRead = $srcStream.Read($buffer, 0, $bufferSize))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t$destStream.Write($buffer, 0, $numberOfBytesRead)\n\t\t\t\t\t\t\t\t\t$destStream.Flush()\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t$numberOfItemsArchived += 1\n\t\t\t\t\t\t\t\t$addItemtoArchiveFileMessage = ($LocalizedData.AddItemtoArchiveFile -f $currentFilePath)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinally\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tIf ($null -ne $currentFileStream)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$currentFileStream.Dispose()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tIf ($null -ne $srcStream)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$srcStream.Dispose()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tIf ($null -ne $destStream)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$destStream.Dispose()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t$currentArchiveEntry = $zipArchive.CreateEntry(\"$relativeFilePath\", $compression)\n\t\t\t\t\t\t$numberOfItemsArchived += 1\n\t\t\t\t\t\t$addItemtoArchiveFileMessage = ($LocalizedData.AddItemtoArchiveFile -f $currentFilePath)\n\t\t\t\t\t}\n\n\t\t\t\t\tif ($null -ne $addItemtoArchiveFileMessage)\n\t\t\t\t\t{\n\t\t\t\t\t\tWrite-Verbose $addItemtoArchiveFileMessage\n\t\t\t\t\t}\n\n\t\t\t\t\t$currentEntryCount += 1\n\t\t\t\t\tProgressBarHelper \"Compress-Archive\" $progressBarStatus $previousSegmentWeight $currentSegmentWeight $sourcePaths.Count  $currentEntryCount\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tIf ($null -ne $zipArchive)\n\t\t\t\t{\n\t\t\t\t\t$zipArchive.Dispose()\n\t\t\t\t}\n\n\t\t\t\tIf ($null -ne $archiveFileStream)\n\t\t\t\t{\n\t\t\t\t\t$archiveFileStream.Dispose()\n\t\t\t\t}\n\n\t\t\t\t# Complete writing progress.\n\t\t\t\tWrite-Progress -Activity \"Compress-Archive\" -Completed\n\t\t\t}\n\n\t\t\treturn $numberOfItemsArchived\n\t\t}\n\n<############################################################################################\n# ValidateArchivePathHelper: This is a helper function used to validate the archive file\n# path & its file format. The only supported archive file format is .zip\n############################################################################################>\n\t\tfunction ValidateArchivePathHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string]\n\t\t\t\t$archiveFile\n\t\t\t)\n\n\t\t\tif ([System.IO.File]::Exists($archiveFile))\n\t\t\t{\n\t\t\t\t$extension = [system.IO.Path]::GetExtension($archiveFile)\n\n\t\t\t\t# Invalid file extension is specifed for the zip file.\n\t\t\t\tif ($extension -ne $zipFileExtension)\n\t\t\t\t{\n\t\t\t\t\t$errorMessage = ($LocalizedData.InvalidZipFileExtensionError -f $extension, $zipFileExtension)\n\t\t\t\t\tThrowTerminatingErrorHelper \"NotSupportedArchiveFileExtension\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $extension\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$errorMessage = ($LocalizedData.PathNotFoundError -f $archiveFile)\n\t\t\t\tThrowTerminatingErrorHelper \"PathNotFound\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $archiveFile\n\t\t\t}\n\t\t}\n\n<############################################################################################\n# ExpandArchiveHelper: This is a helper function used to expand the archive file contents\n# to the specified directory.\n############################################################################################>\n\t\tfunction ExpandArchiveHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string]\n\t\t\t\t$archiveFile,\n\n\t\t\t\t[string]\n\t\t\t\t$expandedDir,\n\n\t\t\t\t[ref]\n\t\t\t\t$expandedItems,\n\n\t\t\t\t[boolean]\n\t\t\t\t$force,\n\n\t\t\t\t[boolean]\n\t\t\t\t$isVerbose,\n\n\t\t\t\t[boolean]\n\t\t\t\t$isConfirm\n\t\t\t)\n\n\t\t\tAdd-CompressionAssemblies\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\t# The existance of archive file has already been validated by ValidateArchivePathHelper\n\t\t\t\t# before calling this helper function.\n\t\t\t\t$archiveFileStreamArgs = @($archiveFile, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)\n\t\t\t\t$archiveFileStream = New-Object -TypeName System.IO.FileStream -ArgumentList $archiveFileStreamArgs\n\n\t\t\t\t$zipArchiveArgs = @($archiveFileStream, [System.IO.Compression.ZipArchiveMode]::Read, $false)\n\t\t\t\t$zipArchive = New-Object -TypeName System.IO.Compression.ZipArchive -ArgumentList $zipArchiveArgs\n\n\t\t\t\tif ($zipArchive.Entries.Count -eq 0)\n\t\t\t\t{\n\t\t\t\t\t$archiveFileIsEmpty = ($LocalizedData.ArchiveFileIsEmpty -f $archiveFile)\n\t\t\t\t\tWrite-Verbose $archiveFileIsEmpty\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t$currentEntryCount = 0\n\t\t\t\t$progressBarStatus = ($LocalizedData.ExpandProgressBarText -f $archiveFile)\n\n\t\t\t\t# The archive entries can either be empty directories or files.\n\t\t\t\tforeach ($currentArchiveEntry in $zipArchive.Entries)\n\t\t\t\t{\n\t\t\t\t\t$currentArchiveEntryPath = Join-Path -Path $expandedDir -ChildPath $currentArchiveEntry.FullName\n\t\t\t\t\t$extension = [system.IO.Path]::GetExtension($currentArchiveEntryPath)\n\n\t\t\t\t\t# The current archive entry is an empty directory\n\t\t\t\t\t# The FullName of the Archive Entry representing a directory would end with a trailing '\\'.\n\t\t\t\t\tif ($extension -eq [string]::Empty -and\n\t\t\t\t\t\t$currentArchiveEntryPath.EndsWith(\"\\\", [StringComparison]::OrdinalIgnoreCase))\n\t\t\t\t\t{\n\t\t\t\t\t\t$pathExists = Test-Path -LiteralPath $currentArchiveEntryPath\n\n\t\t\t\t\t\t# The current archive entry expects an empty directory.\n\t\t\t\t\t\t# Check if the existing directory is empty. If its not empty\n\t\t\t\t\t\t# then it means that user has added this directory by other means.\n\t\t\t\t\t\tif ($pathExists -eq $false)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tNew-Item $currentArchiveEntryPath -ItemType Directory -Confirm:$isConfirm | Out-Null\n\n\t\t\t\t\t\t\tif (Test-Path -LiteralPath $currentArchiveEntryPath -PathType Container)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$addEmptyDirectorytoExpandedPathMessage = ($LocalizedData.AddItemtoArchiveFile -f $currentArchiveEntryPath)\n\t\t\t\t\t\t\t\tWrite-Verbose $addEmptyDirectorytoExpandedPathMessage\n\n\t\t\t\t\t\t\t\t$expandedItems.Value += $currentArchiveEntryPath\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t$currentArchiveEntryFileInfo = New-Object -TypeName System.IO.FileInfo -ArgumentList $currentArchiveEntryPath\n\t\t\t\t\t\t\t$parentDirExists = Test-Path -LiteralPath $currentArchiveEntryFileInfo.DirectoryName -PathType Container\n\n\t\t\t\t\t\t\t# If the Parent directory of the current entry in the archive file does not exist, then create it.\n\t\t\t\t\t\t\tif ($parentDirExists -eq $false)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tNew-Item $currentArchiveEntryFileInfo.DirectoryName -ItemType Directory -Confirm:$isConfirm | Out-Null\n\n\t\t\t\t\t\t\t\tif (!(Test-Path -LiteralPath $currentArchiveEntryFileInfo.DirectoryName -PathType Container))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t# The directory referred by $currentArchiveEntryFileInfo.DirectoryName was not successfully created.\n\t\t\t\t\t\t\t\t\t# This could be because the user has specified -Confirm paramter when Expand-Archive was invoked\n\t\t\t\t\t\t\t\t\t# and authorization was not provided when confirmation was prompted. In such a scenario,\n\t\t\t\t\t\t\t\t\t# we skip the current file in the archive and continue with the remaining archive file contents.\n\t\t\t\t\t\t\t\t\tContinue\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t$expandedItems.Value += $currentArchiveEntryFileInfo.DirectoryName\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t$hasNonTerminatingError = $false\n\n\t\t\t\t\t\t\t# Check if the file in to which the current archive entry contents\n\t\t\t\t\t\t\t# would be expanded already exists.\n\t\t\t\t\t\t\tif ($currentArchiveEntryFileInfo.Exists)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif ($force)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tRemove-Item -LiteralPath $currentArchiveEntryFileInfo.FullName -Force -ErrorVariable ev -Verbose:$isVerbose -Confirm:$isConfirm\n\t\t\t\t\t\t\t\t\tif ($ev -ne $null)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t$hasNonTerminatingError = $true\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif (Test-Path -LiteralPath $currentArchiveEntryFileInfo.FullName -PathType Leaf)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t# The file referred by $currentArchiveEntryFileInfo.FullName was not successfully removed.\n\t\t\t\t\t\t\t\t\t\t# This could be because the user has specified -Confirm paramter when Expand-Archive was invoked\n\t\t\t\t\t\t\t\t\t\t# and authorization was not provided when confirmation was prompted. In such a scenario,\n\t\t\t\t\t\t\t\t\t\t# we skip the current file in the archive and continue with the remaining archive file contents.\n\t\t\t\t\t\t\t\t\t\tContinue\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t# Write non-terminating error to the pipeline.\n\t\t\t\t\t\t\t\t\t$errorMessage = ($LocalizedData.FileExistsError -f $currentArchiveEntryFileInfo.FullName, $archiveFile, $currentArchiveEntryFileInfo.FullName, $currentArchiveEntryFileInfo.FullName)\n\t\t\t\t\t\t\t\t\t$errorRecord = CreateErrorRecordHelper \"ExpandArchiveFileExists\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidOperation) $null $currentArchiveEntryFileInfo.FullName\n\t\t\t\t\t\t\t\t\tWrite-Error -ErrorRecord $errorRecord\n\t\t\t\t\t\t\t\t\t$hasNonTerminatingError = $true\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (!$hasNonTerminatingError)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t[System.IO.Compression.ZipFileExtensions]::ExtractToFile($currentArchiveEntry, $currentArchiveEntryPath, $false)\n\n\t\t\t\t\t\t\t\t# Add the expanded file path to the $expandedItems array,\n\t\t\t\t\t\t\t\t# to keep track of all the expanded files created while expanding the archive file.\n\t\t\t\t\t\t\t\t# If user enters CTRL + C then at that point of time, all these expanded files\n\t\t\t\t\t\t\t\t# would be deleted as part of the clean up process.\n\t\t\t\t\t\t\t\t$expandedItems.Value += $currentArchiveEntryPath\n\n\t\t\t\t\t\t\t\t$addFiletoExpandedPathMessage = ($LocalizedData.CreateFileAtExpandedPath -f $currentArchiveEntryPath)\n\t\t\t\t\t\t\t\tWrite-Verbose $addFiletoExpandedPathMessage\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinally\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tIf ($null -ne $destStream)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$destStream.Dispose()\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tIf ($null -ne $srcStream)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$srcStream.Dispose()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t$currentEntryCount += 1\n\t\t\t\t\t# $currentSegmentWeight is Set to 100 giving equal weightage to each file that is getting expanded.\n\t\t\t\t\t# $previousSegmentWeight is set to 0 as there are no prior segments.\n\t\t\t\t\t$previousSegmentWeight = 0\n\t\t\t\t\t$currentSegmentWeight = 100\n\t\t\t\t\tProgressBarHelper \"Expand-Archive\" $progressBarStatus $previousSegmentWeight $currentSegmentWeight $zipArchive.Entries.Count  $currentEntryCount\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tIf ($null -ne $zipArchive)\n\t\t\t\t{\n\t\t\t\t\t$zipArchive.Dispose()\n\t\t\t\t}\n\n\t\t\t\tIf ($null -ne $archiveFileStream)\n\t\t\t\t{\n\t\t\t\t\t$archiveFileStream.Dispose()\n\t\t\t\t}\n\n\t\t\t\t# Complete writing progress.\n\t\t\t\tWrite-Progress -Activity \"Expand-Archive\" -Completed\n\t\t\t}\n\t\t}\n\n<############################################################################################\n# ProgressBarHelper: This is a helper function used to display progress message.\n# This function is used by both Compress-Archive & Expand-Archive to display archive file\n# creation/expansion progress.\n############################################################################################>\n\t\tfunction ProgressBarHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string]\n\t\t\t\t$cmdletName,\n\n\t\t\t\t[string]\n\t\t\t\t$status,\n\n\t\t\t\t[double]\n\t\t\t\t$previousSegmentWeight,\n\n\t\t\t\t[double]\n\t\t\t\t$currentSegmentWeight,\n\n\t\t\t\t[int]\n\t\t\t\t$totalNumberofEntries,\n\n\t\t\t\t[int]\n\t\t\t\t$currentEntryCount\n\t\t\t)\n\n\t\t\tif ($currentEntryCount -gt 0 -and\n\t\t\t\t$totalNumberofEntries -gt 0 -and\n\t\t\t\t$previousSegmentWeight -ge 0 -and\n\t\t\t\t$currentSegmentWeight -gt 0)\n\t\t\t{\n\t\t\t\t$entryDefaultWeight = $currentSegmentWeight/[double]$totalNumberofEntries\n\n\t\t\t\t$percentComplete = $previousSegmentWeight + ($entryDefaultWeight * $currentEntryCount)\n\t\t\t\tWrite-Progress -Activity $cmdletName -Status $status -PercentComplete $percentComplete\n\t\t\t}\n\t\t}\n\n<############################################################################################\n# CSVHelper: This is a helper function used to append comma after each path specifid by\n# the SourcePath array. This helper function is used to display all the user supplied paths\n# in the WhatIf message.\n############################################################################################>\n\t\tfunction CSVHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string[]]\n\t\t\t\t$sourcePath\n\t\t\t)\n\n\t\t\t# SourcePath has already been validated by the calling funcation.\n\t\t\tif ($sourcePath.Count -gt 1)\n\t\t\t{\n\t\t\t\t$sourcePathInCsvFormat = \"`n\"\n\t\t\t\tfor ($currentIndex = 0; $currentIndex -lt $sourcePath.Count; $currentIndex++)\n\t\t\t\t{\n\t\t\t\t\tif ($currentIndex -eq $sourcePath.Count - 1)\n\t\t\t\t\t{\n\t\t\t\t\t\t$sourcePathInCsvFormat += $sourcePath[$currentIndex]\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t$sourcePathInCsvFormat += $sourcePath[$currentIndex] + \"`n\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$sourcePathInCsvFormat = $sourcePath\n\t\t\t}\n\n\t\t\treturn $sourcePathInCsvFormat\n\t\t}\n\n<############################################################################################\n# ThrowTerminatingErrorHelper: This is a helper function used to throw terminating error.\n############################################################################################>\n\t\tfunction ThrowTerminatingErrorHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string]\n\t\t\t\t$errorId,\n\n\t\t\t\t[string]\n\t\t\t\t$errorMessage,\n\n\t\t\t\t[System.Management.Automation.ErrorCategory]\n\t\t\t\t$errorCategory,\n\n\t\t\t\t[object]\n\t\t\t\t$targetObject,\n\n\t\t\t\t[Exception]\n\t\t\t\t$innerException\n\t\t\t)\n\n\t\t\tif ($innerException -eq $null)\n\t\t\t{\n\t\t\t\t$exception = New-object System.IO.IOException $errorMessage\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$exception = New-Object System.IO.IOException $errorMessage, $innerException\n\t\t\t}\n\n\t\t\t$exception = New-Object System.IO.IOException $errorMessage\n\t\t\t$errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $targetObject\n\t\t\t$PSCmdlet.ThrowTerminatingError($errorRecord)\n\t\t}\n\n<############################################################################################\n# CreateErrorRecordHelper: This is a helper function used to create an ErrorRecord\n############################################################################################>\n\t\tfunction CreateErrorRecordHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string]\n\t\t\t\t$errorId,\n\n\t\t\t\t[string]\n\t\t\t\t$errorMessage,\n\n\t\t\t\t[System.Management.Automation.ErrorCategory]\n\t\t\t\t$errorCategory,\n\n\t\t\t\t[Exception]\n\t\t\t\t$exception,\n\n\t\t\t\t[object]\n\t\t\t\t$targetObject\n\t\t\t)\n\n\t\t\tif ($null -eq $exception)\n\t\t\t{\n\t\t\t\t$exception = New-Object System.IO.IOException $errorMessage\n\t\t\t}\n\n\t\t\t$errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $targetObject\n\t\t\treturn $errorRecord\n\t\t}\n\t\t#endregion Utility Functions\n\n\t\t$inputPaths = @()\n\t\t$destinationParentDir = [system.IO.Path]::GetDirectoryName($DestinationPath)\n\t\tif ($null -eq $destinationParentDir)\n\t\t{\n\t\t\t$errorMessage = ($LocalizedData.InvalidDestinationPath -f $DestinationPath)\n\t\t\tThrowTerminatingErrorHelper \"InvalidArchiveFilePath\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $DestinationPath\n\t\t}\n\n\t\tif ($destinationParentDir -eq [string]::Empty)\n\t\t{\n\t\t\t$destinationParentDir = '.'\n\t\t}\n\n\t\t$achiveFileName = [system.IO.Path]::GetFileName($DestinationPath)\n\t\t$destinationParentDir = GetResolvedPathHelper $destinationParentDir $false $PSCmdlet\n\n\t\tif ($destinationParentDir.Count -gt 1)\n\t\t{\n\t\t\t$errorMessage = ($LocalizedData.InvalidArchiveFilePathError -f $DestinationPath, \"DestinationPath\", \"DestinationPath\")\n\t\t\tThrowTerminatingErrorHelper \"InvalidArchiveFilePath\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $DestinationPath\n\t\t}\n\n\t\tIsValidFileSystemPath $destinationParentDir | Out-Null\n\t\t$DestinationPath = Join-Path -Path $destinationParentDir -ChildPath $achiveFileName\n\n\t\t# GetExtension API does not validate for the actual existance of the path.\n\t\t$extension = [system.IO.Path]::GetExtension($DestinationPath)\n\n\t\t# If user does not specify .Zip extension, we append it.\n\t\tIf ($extension -eq [string]::Empty)\n\t\t{\n\t\t\t$DestinationPathWithOutExtension = $DestinationPath\n\t\t\t$DestinationPath = $DestinationPathWithOutExtension + $zipFileExtension\n\t\t\t$appendArchiveFileExtensionMessage = ($LocalizedData.AppendArchiveFileExtensionMessage -f $DestinationPathWithOutExtension, $DestinationPath)\n\t\t\tWrite-Verbose $appendArchiveFileExtensionMessage\n\t\t}\n\t\telse\n\t\t{\n\t\t\t# Invalid file extension is specified for the zip file to be created.\n\t\t\tif ($extension -ne $zipFileExtension)\n\t\t\t{\n\t\t\t\t$errorMessage = ($LocalizedData.InvalidZipFileExtensionError -f $extension, $zipFileExtension)\n\t\t\t\tThrowTerminatingErrorHelper \"NotSupportedArchiveFileExtension\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $extension\n\t\t\t}\n\t\t}\n\n\t\t$archiveFileExist = Test-Path -LiteralPath $DestinationPath -PathType Leaf\n\n\t\tif ($archiveFileExist -and ($Update -eq $false -and $Force -eq $false))\n\t\t{\n\t\t\t$errorMessage = ($LocalizedData.ZipFileExistError -f $DestinationPath)\n\t\t\tThrowTerminatingErrorHelper \"ArchiveFileExists\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $DestinationPath\n\t\t}\n\n\t\t# If archive file already exists and if -Update is specified, then we check to see\n\t\t# if we have write access permission to update the existing archive file.\n\t\tif ($archiveFileExist -and $Update -eq $true)\n\t\t{\n\t\t\t$item = Get-Item -Path $DestinationPath\n\t\t\tif ($item.Attributes.ToString().Contains(\"ReadOnly\"))\n\t\t\t{\n\t\t\t\t$errorMessage = ($LocalizedData.ArchiveFileIsReadOnly -f $DestinationPath)\n\t\t\t\tThrowTerminatingErrorHelper \"ArchiveFileIsReadOnly\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidOperation) $DestinationPath\n\t\t\t}\n\t\t}\n\n\t\t$isWhatIf = $psboundparameters.ContainsKey(\"WhatIf\")\n\t\tif (!$isWhatIf)\n\t\t{\n\t\t\t$preparingToCompressVerboseMessage = ($LocalizedData.PreparingToCompressVerboseMessage)\n\t\t\tWrite-Verbose $preparingToCompressVerboseMessage\n\n\t\t\t$progressBarStatus = ($LocalizedData.CompressProgressBarText -f $DestinationPath)\n\t\t\tProgressBarHelper \"Compress-Archive\" $progressBarStatus 0 100 100 1\n\t\t}\n\t}\n\tPROCESS\n\t{\n\t\tif ($PsCmdlet.ParameterSetName -eq \"Path\" -or\n\t\t\t$PsCmdlet.ParameterSetName -eq \"PathWithForce\" -or\n\t\t\t$PsCmdlet.ParameterSetName -eq \"PathWithUpdate\")\n\t\t{\n\t\t\t$inputPaths += $Path\n\t\t}\n\n\t\tif ($PsCmdlet.ParameterSetName -eq \"LiteralPath\" -or\n\t\t\t$PsCmdlet.ParameterSetName -eq \"LiteralPathWithForce\" -or\n\t\t\t$PsCmdlet.ParameterSetName -eq \"LiteralPathWithUpdate\")\n\t\t{\n\t\t\t$inputPaths += $LiteralPath\n\t\t}\n\t}\n\tEND\n\t{\n\t\t# If archive file already exists and if -Force is specified, we delete the\n\t\t# existing artchive file and create a brand new one.\n\t\tif (($PsCmdlet.ParameterSetName -eq \"PathWithForce\" -or\n\t\t\t\t$PsCmdlet.ParameterSetName -eq \"LiteralPathWithForce\") -and $archiveFileExist)\n\t\t{\n\t\t\tRemove-Item -Path $DestinationPath -Force -ErrorAction Stop\n\t\t}\n\n\t\t# Validate Source Path depeding on parameter set being used.\n\t\t# The specified source path conatins one or more files or directories that needs\n\t\t# to be compressed.\n\t\t$isLiteralPathUsed = $false\n\t\tif ($PsCmdlet.ParameterSetName -eq \"LiteralPath\" -or\n\t\t\t$PsCmdlet.ParameterSetName -eq \"LiteralPathWithForce\" -or\n\t\t\t$PsCmdlet.ParameterSetName -eq \"LiteralPathWithUpdate\")\n\t\t{\n\t\t\t$isLiteralPathUsed = $true\n\t\t}\n\n\t\tValidateDuplicateFileSystemPath $PsCmdlet.ParameterSetName $inputPaths\n\t\t$resolvedPaths = GetResolvedPathHelper $inputPaths $isLiteralPathUsed $PSCmdlet\n\t\tIsValidFileSystemPath $resolvedPaths | Out-Null\n\n\t\t$sourcePath = $resolvedPaths;\n\n\t\t# CSVHelper: This is a helper function used to append comma after each path specifid by\n\t\t# the $sourcePath array. The comma saperated paths are displayed in the -WhatIf message.\n\t\t$sourcePathInCsvFormat = CSVHelper $sourcePath\n\t\tif ($pscmdlet.ShouldProcess($sourcePathInCsvFormat))\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\t# StopProcessing is not avaliable in Script cmdlets. However the pipleline execution\n\t\t\t\t# is terminated when ever 'CTRL + C' is entered by user to terminate the cmdlet execution.\n\t\t\t\t# The finally block is executed whenever pipleline is terminated.\n\t\t\t\t# $isArchiveFileProcessingComplete variable is used to track if 'CTRL + C' is entered by the\n\t\t\t\t# user.\n\t\t\t\t$isArchiveFileProcessingComplete = $false\n\n\t\t\t\t$numberOfItemsArchived = CompressArchiveHelper $sourcePath $DestinationPath $CompressionLevel $Update\n\n\t\t\t\t$isArchiveFileProcessingComplete = $true\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\t# The $isArchiveFileProcessingComplete would be set to $false if user has typed 'CTRL + C' to\n\t\t\t\t# terminate the cmdlet execution or if an unhandled exception is thrown.\n\t\t\t\t# $numberOfItemsArchived contains the count of number of files or directories add to the archive file.\n\t\t\t\t# If the newly created archive file is empty then we delete it as its not usable.\n\t\t\t\tif (($isArchiveFileProcessingComplete -eq $false) -or\n\t\t\t\t\t($numberOfItemsArchived -eq 0))\n\t\t\t\t{\n\t\t\t\t\t$DeleteArchiveFileMessage = ($LocalizedData.DeleteArchiveFile -f $DestinationPath)\n\t\t\t\t\tWrite-Verbose $DeleteArchiveFileMessage\n\n\t\t\t\t\t# delete the partial archive file created.\n\t\t\t\t\tif (Test-Path $DestinationPath)\n\t\t\t\t\t{\n\t\t\t\t\t\tRemove-Item -LiteralPath $DestinationPath -Force -Recurse -ErrorAction SilentlyContinue\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction Expand-Archive\n{\n\t<#\n\t\t.SYNOPSIS\n\t\t\tExtracts files from a specified archive (zipped) file.\n\n\t\t.DESCRIPTION\n\t\t\tThe Expand-Archive cmdlet extracts files from a specified zipped archive file to a specified destination folder. An archive file allows multiple files to be packaged, and optionally compressed, into a single zipped file for easier distribution and storage.\n\n\t\t.PARAMETER Path\n\t\t\tSpecifies the path to the archive file.\n\n\t\t.PARAMETER LiteralPath\n\t\t\tSpecifies the path to an archive file. Unlike the Path parameter, the value of LiteralPath is used exactly as it is typed. Wildcard characters are not supported. If the path includes escape characters, enclose each escape character in single quotation marks, to instruct Windows PowerShell not to interpret any characters as escape sequences.\n\n\t\t.PARAMETER DestinationPath\n\t\t\tSpecifies the path to the folder in which you want the command to save extracted files. Enter the path to a folder, but do not specify a file name or file name extension. This parameter is required.\n\n\t\t.PARAMETER Force\n\t\t\tForces the command to run without asking for user confirmation.\n\n\t\t.PARAMETER Confirm\n\t\t\tPrompts you for confirmation before running the cmdlet.\n\n\t\t.PARAMETER WhatIf\n\t\t\tShows what would happen if the cmdlet runs. The cmdlet is not run.\n\n\t\t.EXAMPLE\n\t\t\tExample 1: Extract the contents of an archive\n\n\t\t\tPS C:\\>Expand-Archive -LiteralPath C:\\Archives\\Draft.Zip -DestinationPath C:\\Reference\n\n\t\t\tThis command extracts the contents of an existing archive file, Draft.zip, into the folder specified by the DestinationPath parameter, C:\\Reference.\n\n\t\t.EXAMPLE\n\t\t\tExample 2: Extract the contents of an archive in the current folder\n\n\t\t\tPS C:\\>Expand-Archive -Path Draft.Zip -DestinationPath C:\\Reference\n\n\t\t\tThis command extracts the contents of an existing archive file in the current folder, Draft.zip, into the folder specified by the DestinationPath parameter, C:\\Reference.\n\t#>\n\t[CmdletBinding(\n\t\t\t\t   DefaultParameterSetName = \"Path\",\n\t\t\t\t   SupportsShouldProcess = $true,\n\t\t\t\t   HelpUri = \"http://go.microsoft.com/fwlink/?LinkID=393253\")]\n\tparam\n\t(\n\t\t[parameter (\n\t\t\t\t\tmandatory = $true,\n\t\t\t\t\tPosition = 0,\n\t\t\t\t\tParameterSetName = \"Path\",\n\t\t\t\t\tValueFromPipeline = $true,\n\t\t\t\t\tValueFromPipelineByPropertyName = $true)]\n\t\t[ValidateNotNullOrEmpty()]\n\t\t[string]\n\t\t$Path,\n\n\t\t[parameter (\n\t\t\t\t\tmandatory = $true,\n\t\t\t\t\tParameterSetName = \"LiteralPath\",\n\t\t\t\t\tValueFromPipelineByPropertyName = $true)]\n\t\t[ValidateNotNullOrEmpty()]\n\t\t[Alias(\"PSPath\")]\n\t\t[string]\n\t\t$LiteralPath,\n\n\t\t[parameter (mandatory = $false,\n\t\t\t\t\tPosition = 1,\n\t\t\t\t\tValueFromPipeline = $false,\n\t\t\t\t\tValueFromPipelineByPropertyName = $false)]\n\t\t[ValidateNotNullOrEmpty()]\n\t\t[string]\n\t\t$DestinationPath,\n\n\t\t[parameter (mandatory = $false,\n\t\t\t\t\tValueFromPipeline = $false,\n\t\t\t\t\tValueFromPipelineByPropertyName = $false)]\n\t\t[switch]\n\t\t$Force\n\t)\n\n\tBEGIN\n\t{\n\t\tAdd-Type -AssemblyName System.IO.Compression -ErrorAction Ignore\n\t\tAdd-Type -AssemblyName System.IO.Compression.FileSystem -ErrorAction Ignore\n\n\t\t$zipFileExtension = \".zip\"\n\n\t\t$LocalizedData = ConvertFrom-StringData @'\nPathNotFoundError=The path '{0}' either does not exist or is not a valid file system path.\nExpandArchiveInValidDestinationPath=The path '{0}' is not a valid file system directory path.\nInvalidZipFileExtensionError={0} is not a supported archive file format. {1} is the only supported archive file format.\nArchiveFileIsReadOnly=The attributes of the archive file {0} is set to 'ReadOnly' hence it cannot be updated. If you intend to update the existing archive file, remove the 'ReadOnly' attribute on the archive file else use -Force parameter to override and create a new archive file.\nZipFileExistError=The archive file {0} already exists. Use the -Update parameter to update the existing archive file or use the -Force parameter to overwrite the existing archive file.\nDuplicatePathFoundError=The input to {0} parameter contains a duplicate path '{1}'. Provide a unique set of paths as input to {2} parameter.\nArchiveFileIsEmpty=The archive file {0} is empty.\nCompressProgressBarText=The archive file '{0}' creation is in progress...\nExpandProgressBarText=The archive file '{0}' expansion is in progress...\nAppendArchiveFileExtensionMessage=The archive file path '{0}' supplied to the DestinationPath patameter does not include .zip extension. Hence .zip is appended to the supplied DestinationPath path and the archive file would be created at '{1}'.\nAddItemtoArchiveFile=Adding '{0}'.\nCreateFileAtExpandedPath=Created '{0}'.\nInvalidArchiveFilePathError=The archive file path '{0}' specified as input to the {1} parameter is resolving to multiple file system paths. Provide a unique path to the {2} parameter where the archive file has to be created.\nInvalidExpandedDirPathError=The directory path '{0}' specified as input to the DestinationPath parameter is resolving to multiple file system paths. Provide a unique path to the Destination parameter where the archive file contents have to be expanded.\nFileExistsError=Failed to create file '{0}' while expanding the archive file '{1}' contents as the file '{2}' already exists. Use the -Force parameter if you want to overwrite the existing directory '{3}' contents when expanding the archive file.\nDeleteArchiveFile=The partially created archive file '{0}' is deleted as it is not usable.\nInvalidDestinationPath=The destination path '{0}' does not contain a valid archive file name.\nPreparingToCompressVerboseMessage=Preparing to compress...\nPreparingToExpandVerboseMessage=Preparing to expand...\n'@\n\n\t\t#region Utility Functions\n\t\tfunction GetResolvedPathHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string[]]\n\t\t\t\t$path,\n\n\t\t\t\t[boolean]\n\t\t\t\t$isLiteralPath,\n\n\t\t\t\t[System.Management.Automation.PSCmdlet]\n\t\t\t\t$callerPSCmdlet\n\t\t\t)\n\n\t\t\t$resolvedPaths = @()\n\n\t\t\t# null and empty check are are already done on Path parameter at the cmdlet layer.\n\t\t\tforeach ($currentPath in $path)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tif ($isLiteralPath)\n\t\t\t\t\t{\n\t\t\t\t\t\t$currentResolvedPaths = Resolve-Path -LiteralPath $currentPath -ErrorAction Stop\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t$currentResolvedPaths = Resolve-Path -Path $currentPath -ErrorAction Stop\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t\t$errorMessage = ($LocalizedData.PathNotFoundError -f $currentPath)\n\t\t\t\t\t$exception = New-Object System.InvalidOperationException $errorMessage, $_.Exception\n\t\t\t\t\t$errorRecord = CreateErrorRecordHelper \"ArchiveCmdletPathNotFound\" $null ([System.Management.Automation.ErrorCategory]::InvalidArgument) $exception $currentPath\n\t\t\t\t\t$callerPSCmdlet.ThrowTerminatingError($errorRecord)\n\t\t\t\t}\n\n\t\t\t\tforeach ($currentResolvedPath in $currentResolvedPaths)\n\t\t\t\t{\n\t\t\t\t\t$resolvedPaths += $currentResolvedPath.ProviderPath\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$resolvedPaths\n\t\t}\n\n\t\tfunction Add-CompressionAssemblies\n\t\t{\n\n\t\t\tif ($PSEdition -eq \"Desktop\")\n\t\t\t{\n\t\t\t\tAdd-Type -AssemblyName System.IO.Compression\n\t\t\t\tAdd-Type -AssemblyName System.IO.Compression.FileSystem\n\t\t\t}\n\t\t}\n\n\t\tfunction IsValidFileSystemPath\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string[]]\n\t\t\t\t$path\n\t\t\t)\n\n\t\t\t$result = $true;\n\n\t\t\t# null and empty check are are already done on Path parameter at the cmdlet layer.\n\t\t\tforeach ($currentPath in $path)\n\t\t\t{\n\t\t\t\tif (!([System.IO.File]::Exists($currentPath) -or [System.IO.Directory]::Exists($currentPath)))\n\t\t\t\t{\n\t\t\t\t\t$errorMessage = ($LocalizedData.PathNotFoundError -f $currentPath)\n\t\t\t\t\tThrowTerminatingErrorHelper \"PathNotFound\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $currentPath\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn $result;\n\t\t}\n\n\n\t\tfunction ValidateDuplicateFileSystemPath\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string]\n\t\t\t\t$inputParameter,\n\n\t\t\t\t[string[]]\n\t\t\t\t$path\n\t\t\t)\n\n\t\t\t$uniqueInputPaths = @()\n\n\t\t\t# null and empty check are are already done on Path parameter at the cmdlet layer.\n\t\t\tforeach ($currentPath in $path)\n\t\t\t{\n\t\t\t\t$currentInputPath = $currentPath.ToUpper()\n\t\t\t\tif ($uniqueInputPaths.Contains($currentInputPath))\n\t\t\t\t{\n\t\t\t\t\t$errorMessage = ($LocalizedData.DuplicatePathFoundError -f $inputParameter, $currentPath, $inputParameter)\n\t\t\t\t\tThrowTerminatingErrorHelper \"DuplicatePathFound\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $currentPath\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t$uniqueInputPaths += $currentInputPath\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfunction CompressionLevelMapper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string]\n\t\t\t\t$compressionLevel\n\t\t\t)\n\n\t\t\t$compressionLevelFormat = [System.IO.Compression.CompressionLevel]::Optimal\n\n\t\t\t# CompressionLevel format is already validated at the cmdlet layer.\n\t\t\tswitch ($compressionLevel.ToString())\n\t\t\t{\n\t\t\t\t\"Fastest\"\n\t\t\t\t{\n\t\t\t\t\t$compressionLevelFormat = [System.IO.Compression.CompressionLevel]::Fastest\n\t\t\t\t}\n\t\t\t\t\"NoCompression\"\n\t\t\t\t{\n\t\t\t\t\t$compressionLevelFormat = [System.IO.Compression.CompressionLevel]::NoCompression\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn $compressionLevelFormat\n\t\t}\n\n\t\tfunction CompressArchiveHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string[]]\n\t\t\t\t$sourcePath,\n\n\t\t\t\t[string]\n\t\t\t\t$destinationPath,\n\n\t\t\t\t[string]\n\t\t\t\t$compressionLevel,\n\n\t\t\t\t[bool]\n\t\t\t\t$isUpdateMode\n\t\t\t)\n\n\t\t\t$numberOfItemsArchived = 0\n\t\t\t$sourceFilePaths = @()\n\t\t\t$sourceDirPaths = @()\n\n\t\t\tforeach ($currentPath in $sourcePath)\n\t\t\t{\n\t\t\t\t$result = Test-Path -LiteralPath $currentPath -PathType Leaf\n\t\t\t\tif ($result -eq $true)\n\t\t\t\t{\n\t\t\t\t\t$sourceFilePaths += $currentPath\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t$sourceDirPaths += $currentPath\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t# The Soure Path contains one or more directory (this directory can have files under it) and no files to be compressed.\n\t\t\tif ($sourceFilePaths.Count -eq 0 -and $sourceDirPaths.Count -gt 0)\n\t\t\t{\n\t\t\t\t$currentSegmentWeight = 100/[double]$sourceDirPaths.Count\n\t\t\t\t$previousSegmentWeight = 0\n\t\t\t\tforeach ($currentSourceDirPath in $sourceDirPaths)\n\t\t\t\t{\n\t\t\t\t\t$count = CompressSingleDirHelper $currentSourceDirPath $destinationPath $compressionLevel $true $isUpdateMode $previousSegmentWeight $currentSegmentWeight\n\t\t\t\t\t$numberOfItemsArchived += $count\n\t\t\t\t\t$previousSegmentWeight += $currentSegmentWeight\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t# The Soure Path contains only files to be compressed.\n\t\t\telseIf ($sourceFilePaths.Count -gt 0 -and $sourceDirPaths.Count -eq 0)\n\t\t\t{\n\t\t\t\t# $previousSegmentWeight is equal to 0 as there are no prior segments.\n\t\t\t\t# $currentSegmentWeight is set to 100 as all files have equal weightage.\n\t\t\t\t$previousSegmentWeight = 0\n\t\t\t\t$currentSegmentWeight = 100\n\n\t\t\t\t$numberOfItemsArchived = CompressFilesHelper $sourceFilePaths $destinationPath $compressionLevel $isUpdateMode $previousSegmentWeight $currentSegmentWeight\n\t\t\t}\n\t\t\t# The Soure Path contains one or more files and one or more directories (this directory can have files under it) to be compressed.\n\t\t\telseif ($sourceFilePaths.Count -gt 0 -and $sourceDirPaths.Count -gt 0)\n\t\t\t{\n\t\t\t\t# each directory is considered as an individual segments & all the individual files are clubed in to a separate sgemnet.\n\t\t\t\t$currentSegmentWeight = 100/[double]($sourceDirPaths.Count + 1)\n\t\t\t\t$previousSegmentWeight = 0\n\n\t\t\t\tforeach ($currentSourceDirPath in $sourceDirPaths)\n\t\t\t\t{\n\t\t\t\t\t$count = CompressSingleDirHelper $currentSourceDirPath $destinationPath $compressionLevel $true $isUpdateMode $previousSegmentWeight $currentSegmentWeight\n\t\t\t\t\t$numberOfItemsArchived += $count\n\t\t\t\t\t$previousSegmentWeight += $currentSegmentWeight\n\t\t\t\t}\n\n\t\t\t\t$count = CompressFilesHelper $sourceFilePaths $destinationPath $compressionLevel $isUpdateMode $previousSegmentWeight $currentSegmentWeight\n\t\t\t\t$numberOfItemsArchived += $count\n\t\t\t}\n\n\t\t\treturn $numberOfItemsArchived\n\t\t}\n\n\t\tfunction CompressFilesHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string[]]\n\t\t\t\t$sourceFilePaths,\n\n\t\t\t\t[string]\n\t\t\t\t$destinationPath,\n\n\t\t\t\t[string]\n\t\t\t\t$compressionLevel,\n\n\t\t\t\t[bool]\n\t\t\t\t$isUpdateMode,\n\n\t\t\t\t[double]\n\t\t\t\t$previousSegmentWeight,\n\n\t\t\t\t[double]\n\t\t\t\t$currentSegmentWeight\n\t\t\t)\n\n\t\t\t$numberOfItemsArchived = ZipArchiveHelper $sourceFilePaths $destinationPath $compressionLevel $isUpdateMode $null $previousSegmentWeight $currentSegmentWeight\n\n\t\t\treturn $numberOfItemsArchived\n\t\t}\n\n\t\tfunction CompressSingleDirHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string]\n\t\t\t\t$sourceDirPath,\n\n\t\t\t\t[string]\n\t\t\t\t$destinationPath,\n\n\t\t\t\t[string]\n\t\t\t\t$compressionLevel,\n\n\t\t\t\t[bool]\n\t\t\t\t$useParentDirAsRoot,\n\n\t\t\t\t[bool]\n\t\t\t\t$isUpdateMode,\n\n\t\t\t\t[double]\n\t\t\t\t$previousSegmentWeight,\n\n\t\t\t\t[double]\n\t\t\t\t$currentSegmentWeight\n\t\t\t)\n\n\t\t\t[System.Collections.Generic.List[System.String]]$subDirFiles = @()\n\n\t\t\tif ($useParentDirAsRoot)\n\t\t\t{\n\t\t\t\t$sourceDirInfo = New-Object -TypeName System.IO.DirectoryInfo -ArgumentList $sourceDirPath\n\t\t\t\t$sourceDirFullName = $sourceDirInfo.Parent.FullName\n\n\t\t\t\t# If the directory is present at the drive level the DirectoryInfo.Parent include '\\' example: C:\\\n\t\t\t\t# On the other hand if the directory exists at a deper level then DirectoryInfo.Parent\n\t\t\t\t# has just the path (without an ending '\\'). example C:\\source\n\t\t\t\tif ($sourceDirFullName.Length -eq 3)\n\t\t\t\t{\n\t\t\t\t\t$modifiedSourceDirFullName = $sourceDirFullName\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t$modifiedSourceDirFullName = $sourceDirFullName + \"\\\"\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$sourceDirFullName = $sourceDirPath\n\t\t\t\t$modifiedSourceDirFullName = $sourceDirFullName + \"\\\"\n\t\t\t}\n\n\t\t\t$dirContents = Get-ChildItem -LiteralPath $sourceDirPath -Recurse\n\t\t\tforeach ($currentContent in $dirContents)\n\t\t\t{\n\t\t\t\t$isContainer = $currentContent -is [System.IO.DirectoryInfo]\n\t\t\t\tif (!$isContainer)\n\t\t\t\t{\n\t\t\t\t\t$subDirFiles.Add($currentContent.FullName)\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t# The currentContent points to a directory.\n\t\t\t\t\t# We need to check if the directory is an empty directory, if so such a\n\t\t\t\t\t# directory has to be explictly added to the archive file.\n\t\t\t\t\t# if there are no files in the directory the GetFiles() API returns an empty array.\n\t\t\t\t\t$files = $currentContent.GetFiles()\n\t\t\t\t\tif ($files.Count -eq 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t$subDirFiles.Add($currentContent.FullName + \"\\\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$numberOfItemsArchived = ZipArchiveHelper $subDirFiles.ToArray() $destinationPath $compressionLevel $isUpdateMode $modifiedSourceDirFullName $previousSegmentWeight $currentSegmentWeight\n\n\t\t\treturn $numberOfItemsArchived\n\t\t}\n\n\t\tfunction ZipArchiveHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[System.Collections.Generic.List[System.String]]\n\t\t\t\t$sourcePaths,\n\n\t\t\t\t[string]\n\t\t\t\t$destinationPath,\n\n\t\t\t\t[string]\n\t\t\t\t$compressionLevel,\n\n\t\t\t\t[bool]\n\t\t\t\t$isUpdateMode,\n\n\t\t\t\t[string]\n\t\t\t\t$modifiedSourceDirFullName,\n\n\t\t\t\t[double]\n\t\t\t\t$previousSegmentWeight,\n\n\t\t\t\t[double]\n\t\t\t\t$currentSegmentWeight\n\t\t\t)\n\n\t\t\t$numberOfItemsArchived = 0\n\t\t\t$fileMode = [System.IO.FileMode]::Create\n\t\t\t$result = Test-Path -LiteralPath $DestinationPath -PathType Leaf\n\t\t\tif ($result -eq $true)\n\t\t\t{\n\t\t\t\t$fileMode = [System.IO.FileMode]::Open\n\t\t\t}\n\n\t\t\tAdd-CompressionAssemblies\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\t# At this point we are sure that the archive file has write access.\n\t\t\t\t$archiveFileStreamArgs = @($destinationPath, $fileMode)\n\t\t\t\t$archiveFileStream = New-Object -TypeName System.IO.FileStream -ArgumentList $archiveFileStreamArgs\n\n\t\t\t\t$zipArchiveArgs = @($archiveFileStream, [System.IO.Compression.ZipArchiveMode]::Update, $false)\n\t\t\t\t$zipArchive = New-Object -TypeName System.IO.Compression.ZipArchive -ArgumentList $zipArchiveArgs\n\n\t\t\t\t$currentEntryCount = 0\n\t\t\t\t$progressBarStatus = ($LocalizedData.CompressProgressBarText -f $destinationPath)\n\t\t\t\t$bufferSize = 4kb\n\t\t\t\t$buffer = New-Object Byte[] $bufferSize\n\n\t\t\t\tforeach ($currentFilePath in $sourcePaths)\n\t\t\t\t{\n\t\t\t\t\tif ($modifiedSourceDirFullName -ne $null -and $modifiedSourceDirFullName.Length -gt 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t$index = $currentFilePath.IndexOf($modifiedSourceDirFullName, [System.StringComparison]::OrdinalIgnoreCase)\n\t\t\t\t\t\t$currentFilePathSubString = $currentFilePath.Substring($index, $modifiedSourceDirFullName.Length)\n\t\t\t\t\t\t$relativeFilePath = $currentFilePath.Replace($currentFilePathSubString, \"\").Trim()\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t$relativeFilePath = [System.IO.Path]::GetFileName($currentFilePath)\n\t\t\t\t\t}\n\n\t\t\t\t\t# Update mode is selected.\n\t\t\t\t\t# Check to see if archive file already contains one or more zip files in it.\n\t\t\t\t\tif ($isUpdateMode -eq $true -and $zipArchive.Entries.Count -gt 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t$entryToBeUpdated = $null\n\n\t\t\t\t\t\t# Check if the file already exists in the archive file.\n\t\t\t\t\t\t# If so replace it with new file from the input source.\n\t\t\t\t\t\t# If the file does not exist in the archive file then default to\n\t\t\t\t\t\t# create mode and create the entry in the archive file.\n\n\t\t\t\t\t\tforeach ($currentArchiveEntry in $zipArchive.Entries)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif ($currentArchiveEntry.FullName -eq $relativeFilePath)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$entryToBeUpdated = $currentArchiveEntry\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ($entryToBeUpdated -ne $null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t$addItemtoArchiveFileMessage = ($LocalizedData.AddItemtoArchiveFile -f $currentFilePath)\n\t\t\t\t\t\t\t$entryToBeUpdated.Delete()\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t$compression = CompressionLevelMapper $compressionLevel\n\n\t\t\t\t\t# If a directory needs to be added to an archive file,\n\t\t\t\t\t# by convention the .Net API's expect the path of the diretcory\n\t\t\t\t\t# to end with '\\' to detect the path as an directory.\n\t\t\t\t\tif (!$relativeFilePath.EndsWith(\"\\\", [StringComparison]::OrdinalIgnoreCase))\n\t\t\t\t\t{\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$currentFileStream = [System.IO.File]::Open($currentFilePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t# Failed to access the file. Write a non terminating error to the pipeline\n\t\t\t\t\t\t\t\t# and move on with the remaining files.\n\t\t\t\t\t\t\t\t$exception = $_.Exception\n\t\t\t\t\t\t\t\tif ($null -ne $_.Exception -and\n\t\t\t\t\t\t\t\t\t$null -ne $_.Exception.InnerException)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t$exception = $_.Exception.InnerException\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t$errorRecord = CreateErrorRecordHelper \"CompressArchiveUnauthorizedAccessError\" $null ([System.Management.Automation.ErrorCategory]::PermissionDenied) $exception $currentFilePath\n\t\t\t\t\t\t\t\tWrite-Error -ErrorRecord $errorRecord\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ($null -ne $currentFileStream)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$srcStream = New-Object System.IO.BinaryReader $currentFileStream\n\n\t\t\t\t\t\t\t\t$currentArchiveEntry = $zipArchive.CreateEntry($relativeFilePath, $compression)\n\n\t\t\t\t\t\t\t\t# Updating  the File Creation time so that the same timestamp would be retained after expanding the compressed file.\n\t\t\t\t\t\t\t\t# At this point we are sure that Get-ChildItem would succeed.\n\t\t\t\t\t\t\t\t$currentArchiveEntry.LastWriteTime = (Get-Item -LiteralPath $currentFilePath).LastWriteTime\n\n\t\t\t\t\t\t\t\t$destStream = New-Object System.IO.BinaryWriter $currentArchiveEntry.Open()\n\n\t\t\t\t\t\t\t\twhile ($numberOfBytesRead = $srcStream.Read($buffer, 0, $bufferSize))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t$destStream.Write($buffer, 0, $numberOfBytesRead)\n\t\t\t\t\t\t\t\t\t$destStream.Flush()\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t$numberOfItemsArchived += 1\n\t\t\t\t\t\t\t\t$addItemtoArchiveFileMessage = ($LocalizedData.AddItemtoArchiveFile -f $currentFilePath)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinally\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tIf ($null -ne $currentFileStream)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$currentFileStream.Dispose()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tIf ($null -ne $srcStream)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$srcStream.Dispose()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tIf ($null -ne $destStream)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$destStream.Dispose()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t$currentArchiveEntry = $zipArchive.CreateEntry(\"$relativeFilePath\", $compression)\n\t\t\t\t\t\t$numberOfItemsArchived += 1\n\t\t\t\t\t\t$addItemtoArchiveFileMessage = ($LocalizedData.AddItemtoArchiveFile -f $currentFilePath)\n\t\t\t\t\t}\n\n\t\t\t\t\tif ($null -ne $addItemtoArchiveFileMessage)\n\t\t\t\t\t{\n\t\t\t\t\t\tWrite-Verbose $addItemtoArchiveFileMessage\n\t\t\t\t\t}\n\n\t\t\t\t\t$currentEntryCount += 1\n\t\t\t\t\tProgressBarHelper \"Compress-Archive\" $progressBarStatus $previousSegmentWeight $currentSegmentWeight $sourcePaths.Count  $currentEntryCount\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tIf ($null -ne $zipArchive)\n\t\t\t\t{\n\t\t\t\t\t$zipArchive.Dispose()\n\t\t\t\t}\n\n\t\t\t\tIf ($null -ne $archiveFileStream)\n\t\t\t\t{\n\t\t\t\t\t$archiveFileStream.Dispose()\n\t\t\t\t}\n\n\t\t\t\t# Complete writing progress.\n\t\t\t\tWrite-Progress -Activity \"Compress-Archive\" -Completed\n\t\t\t}\n\n\t\t\treturn $numberOfItemsArchived\n\t\t}\n\n<############################################################################################\n# ValidateArchivePathHelper: This is a helper function used to validate the archive file\n# path & its file format. The only supported archive file format is .zip\n############################################################################################>\n\t\tfunction ValidateArchivePathHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string]\n\t\t\t\t$archiveFile\n\t\t\t)\n\n\t\t\tif ([System.IO.File]::Exists($archiveFile))\n\t\t\t{\n\t\t\t\t$extension = [system.IO.Path]::GetExtension($archiveFile)\n\n\t\t\t\t# Invalid file extension is specifed for the zip file.\n\t\t\t\tif ($extension -ne $zipFileExtension)\n\t\t\t\t{\n\t\t\t\t\t$errorMessage = ($LocalizedData.InvalidZipFileExtensionError -f $extension, $zipFileExtension)\n\t\t\t\t\tThrowTerminatingErrorHelper \"NotSupportedArchiveFileExtension\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $extension\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$errorMessage = ($LocalizedData.PathNotFoundError -f $archiveFile)\n\t\t\t\tThrowTerminatingErrorHelper \"PathNotFound\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $archiveFile\n\t\t\t}\n\t\t}\n\n<############################################################################################\n# ExpandArchiveHelper: This is a helper function used to expand the archive file contents\n# to the specified directory.\n############################################################################################>\n\t\tfunction ExpandArchiveHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string]\n\t\t\t\t$archiveFile,\n\n\t\t\t\t[string]\n\t\t\t\t$expandedDir,\n\n\t\t\t\t[ref]\n\t\t\t\t$expandedItems,\n\n\t\t\t\t[boolean]\n\t\t\t\t$force,\n\n\t\t\t\t[boolean]\n\t\t\t\t$isVerbose,\n\n\t\t\t\t[boolean]\n\t\t\t\t$isConfirm\n\t\t\t)\n\n\t\t\tAdd-CompressionAssemblies\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\t# The existance of archive file has already been validated by ValidateArchivePathHelper\n\t\t\t\t# before calling this helper function.\n\t\t\t\t$archiveFileStreamArgs = @($archiveFile, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)\n\t\t\t\t$archiveFileStream = New-Object -TypeName System.IO.FileStream -ArgumentList $archiveFileStreamArgs\n\n\t\t\t\t$zipArchiveArgs = @($archiveFileStream, [System.IO.Compression.ZipArchiveMode]::Read, $false)\n\t\t\t\t$zipArchive = New-Object -TypeName System.IO.Compression.ZipArchive -ArgumentList $zipArchiveArgs\n\n\t\t\t\tif ($zipArchive.Entries.Count -eq 0)\n\t\t\t\t{\n\t\t\t\t\t$archiveFileIsEmpty = ($LocalizedData.ArchiveFileIsEmpty -f $archiveFile)\n\t\t\t\t\tWrite-Verbose $archiveFileIsEmpty\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t$currentEntryCount = 0\n\t\t\t\t$progressBarStatus = ($LocalizedData.ExpandProgressBarText -f $archiveFile)\n\n\t\t\t\t# The archive entries can either be empty directories or files.\n\t\t\t\tforeach ($currentArchiveEntry in $zipArchive.Entries)\n\t\t\t\t{\n\t\t\t\t\t$currentArchiveEntryPath = Join-Path -Path $expandedDir -ChildPath $currentArchiveEntry.FullName\n\t\t\t\t\t$extension = [system.IO.Path]::GetExtension($currentArchiveEntryPath)\n\n\t\t\t\t\t# The current archive entry is an empty directory\n\t\t\t\t\t# The FullName of the Archive Entry representing a directory would end with a trailing '\\'.\n\t\t\t\t\tif ($extension -eq [string]::Empty -and\n\t\t\t\t\t\t$currentArchiveEntryPath.EndsWith(\"\\\", [StringComparison]::OrdinalIgnoreCase))\n\t\t\t\t\t{\n\t\t\t\t\t\t$pathExists = Test-Path -LiteralPath $currentArchiveEntryPath\n\n\t\t\t\t\t\t# The current archive entry expects an empty directory.\n\t\t\t\t\t\t# Check if the existing directory is empty. If its not empty\n\t\t\t\t\t\t# then it means that user has added this directory by other means.\n\t\t\t\t\t\tif ($pathExists -eq $false)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tNew-Item $currentArchiveEntryPath -ItemType Directory -Confirm:$isConfirm | Out-Null\n\n\t\t\t\t\t\t\tif (Test-Path -LiteralPath $currentArchiveEntryPath -PathType Container)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$addEmptyDirectorytoExpandedPathMessage = ($LocalizedData.AddItemtoArchiveFile -f $currentArchiveEntryPath)\n\t\t\t\t\t\t\t\tWrite-Verbose $addEmptyDirectorytoExpandedPathMessage\n\n\t\t\t\t\t\t\t\t$expandedItems.Value += $currentArchiveEntryPath\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t$currentArchiveEntryFileInfo = New-Object -TypeName System.IO.FileInfo -ArgumentList $currentArchiveEntryPath\n\t\t\t\t\t\t\t$parentDirExists = Test-Path -LiteralPath $currentArchiveEntryFileInfo.DirectoryName -PathType Container\n\n\t\t\t\t\t\t\t# If the Parent directory of the current entry in the archive file does not exist, then create it.\n\t\t\t\t\t\t\tif ($parentDirExists -eq $false)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tNew-Item $currentArchiveEntryFileInfo.DirectoryName -ItemType Directory -Confirm:$isConfirm | Out-Null\n\n\t\t\t\t\t\t\t\tif (!(Test-Path -LiteralPath $currentArchiveEntryFileInfo.DirectoryName -PathType Container))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t# The directory referred by $currentArchiveEntryFileInfo.DirectoryName was not successfully created.\n\t\t\t\t\t\t\t\t\t# This could be because the user has specified -Confirm paramter when Expand-Archive was invoked\n\t\t\t\t\t\t\t\t\t# and authorization was not provided when confirmation was prompted. In such a scenario,\n\t\t\t\t\t\t\t\t\t# we skip the current file in the archive and continue with the remaining archive file contents.\n\t\t\t\t\t\t\t\t\tContinue\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t$expandedItems.Value += $currentArchiveEntryFileInfo.DirectoryName\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t$hasNonTerminatingError = $false\n\n\t\t\t\t\t\t\t# Check if the file in to which the current archive entry contents\n\t\t\t\t\t\t\t# would be expanded already exists.\n\t\t\t\t\t\t\tif ($currentArchiveEntryFileInfo.Exists)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif ($force)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tRemove-Item -LiteralPath $currentArchiveEntryFileInfo.FullName -Force -ErrorVariable ev -Verbose:$isVerbose -Confirm:$isConfirm\n\t\t\t\t\t\t\t\t\tif ($ev -ne $null)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t$hasNonTerminatingError = $true\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif (Test-Path -LiteralPath $currentArchiveEntryFileInfo.FullName -PathType Leaf)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t# The file referred by $currentArchiveEntryFileInfo.FullName was not successfully removed.\n\t\t\t\t\t\t\t\t\t\t# This could be because the user has specified -Confirm paramter when Expand-Archive was invoked\n\t\t\t\t\t\t\t\t\t\t# and authorization was not provided when confirmation was prompted. In such a scenario,\n\t\t\t\t\t\t\t\t\t\t# we skip the current file in the archive and continue with the remaining archive file contents.\n\t\t\t\t\t\t\t\t\t\tContinue\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t# Write non-terminating error to the pipeline.\n\t\t\t\t\t\t\t\t\t$errorMessage = ($LocalizedData.FileExistsError -f $currentArchiveEntryFileInfo.FullName, $archiveFile, $currentArchiveEntryFileInfo.FullName, $currentArchiveEntryFileInfo.FullName)\n\t\t\t\t\t\t\t\t\t$errorRecord = CreateErrorRecordHelper \"ExpandArchiveFileExists\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidOperation) $null $currentArchiveEntryFileInfo.FullName\n\t\t\t\t\t\t\t\t\tWrite-Error -ErrorRecord $errorRecord\n\t\t\t\t\t\t\t\t\t$hasNonTerminatingError = $true\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (!$hasNonTerminatingError)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t[System.IO.Compression.ZipFileExtensions]::ExtractToFile($currentArchiveEntry, $currentArchiveEntryPath, $false)\n\n\t\t\t\t\t\t\t\t# Add the expanded file path to the $expandedItems array,\n\t\t\t\t\t\t\t\t# to keep track of all the expanded files created while expanding the archive file.\n\t\t\t\t\t\t\t\t# If user enters CTRL + C then at that point of time, all these expanded files\n\t\t\t\t\t\t\t\t# would be deleted as part of the clean up process.\n\t\t\t\t\t\t\t\t$expandedItems.Value += $currentArchiveEntryPath\n\n\t\t\t\t\t\t\t\t$addFiletoExpandedPathMessage = ($LocalizedData.CreateFileAtExpandedPath -f $currentArchiveEntryPath)\n\t\t\t\t\t\t\t\tWrite-Verbose $addFiletoExpandedPathMessage\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinally\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tIf ($null -ne $destStream)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$destStream.Dispose()\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tIf ($null -ne $srcStream)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$srcStream.Dispose()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t$currentEntryCount += 1\n\t\t\t\t\t# $currentSegmentWeight is Set to 100 giving equal weightage to each file that is getting expanded.\n\t\t\t\t\t# $previousSegmentWeight is set to 0 as there are no prior segments.\n\t\t\t\t\t$previousSegmentWeight = 0\n\t\t\t\t\t$currentSegmentWeight = 100\n\t\t\t\t\tProgressBarHelper \"Expand-Archive\" $progressBarStatus $previousSegmentWeight $currentSegmentWeight $zipArchive.Entries.Count  $currentEntryCount\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tIf ($null -ne $zipArchive)\n\t\t\t\t{\n\t\t\t\t\t$zipArchive.Dispose()\n\t\t\t\t}\n\n\t\t\t\tIf ($null -ne $archiveFileStream)\n\t\t\t\t{\n\t\t\t\t\t$archiveFileStream.Dispose()\n\t\t\t\t}\n\n\t\t\t\t# Complete writing progress.\n\t\t\t\tWrite-Progress -Activity \"Expand-Archive\" -Completed\n\t\t\t}\n\t\t}\n\n<############################################################################################\n# ProgressBarHelper: This is a helper function used to display progress message.\n# This function is used by both Compress-Archive & Expand-Archive to display archive file\n# creation/expansion progress.\n############################################################################################>\n\t\tfunction ProgressBarHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string]\n\t\t\t\t$cmdletName,\n\n\t\t\t\t[string]\n\t\t\t\t$status,\n\n\t\t\t\t[double]\n\t\t\t\t$previousSegmentWeight,\n\n\t\t\t\t[double]\n\t\t\t\t$currentSegmentWeight,\n\n\t\t\t\t[int]\n\t\t\t\t$totalNumberofEntries,\n\n\t\t\t\t[int]\n\t\t\t\t$currentEntryCount\n\t\t\t)\n\n\t\t\tif ($currentEntryCount -gt 0 -and\n\t\t\t\t$totalNumberofEntries -gt 0 -and\n\t\t\t\t$previousSegmentWeight -ge 0 -and\n\t\t\t\t$currentSegmentWeight -gt 0)\n\t\t\t{\n\t\t\t\t$entryDefaultWeight = $currentSegmentWeight/[double]$totalNumberofEntries\n\n\t\t\t\t$percentComplete = $previousSegmentWeight + ($entryDefaultWeight * $currentEntryCount)\n\t\t\t\tWrite-Progress -Activity $cmdletName -Status $status -PercentComplete $percentComplete\n\t\t\t}\n\t\t}\n\n<############################################################################################\n# CSVHelper: This is a helper function used to append comma after each path specifid by\n# the SourcePath array. This helper function is used to display all the user supplied paths\n# in the WhatIf message.\n############################################################################################>\n\t\tfunction CSVHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string[]]\n\t\t\t\t$sourcePath\n\t\t\t)\n\n\t\t\t# SourcePath has already been validated by the calling funcation.\n\t\t\tif ($sourcePath.Count -gt 1)\n\t\t\t{\n\t\t\t\t$sourcePathInCsvFormat = \"`n\"\n\t\t\t\tfor ($currentIndex = 0; $currentIndex -lt $sourcePath.Count; $currentIndex++)\n\t\t\t\t{\n\t\t\t\t\tif ($currentIndex -eq $sourcePath.Count - 1)\n\t\t\t\t\t{\n\t\t\t\t\t\t$sourcePathInCsvFormat += $sourcePath[$currentIndex]\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t$sourcePathInCsvFormat += $sourcePath[$currentIndex] + \"`n\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$sourcePathInCsvFormat = $sourcePath\n\t\t\t}\n\n\t\t\treturn $sourcePathInCsvFormat\n\t\t}\n\n<############################################################################################\n# ThrowTerminatingErrorHelper: This is a helper function used to throw terminating error.\n############################################################################################>\n\t\tfunction ThrowTerminatingErrorHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string]\n\t\t\t\t$errorId,\n\n\t\t\t\t[string]\n\t\t\t\t$errorMessage,\n\n\t\t\t\t[System.Management.Automation.ErrorCategory]\n\t\t\t\t$errorCategory,\n\n\t\t\t\t[object]\n\t\t\t\t$targetObject,\n\n\t\t\t\t[Exception]\n\t\t\t\t$innerException\n\t\t\t)\n\n\t\t\tif ($innerException -eq $null)\n\t\t\t{\n\t\t\t\t$exception = New-object System.IO.IOException $errorMessage\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$exception = New-Object System.IO.IOException $errorMessage, $innerException\n\t\t\t}\n\n\t\t\t$exception = New-Object System.IO.IOException $errorMessage\n\t\t\t$errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $targetObject\n\t\t\t$PSCmdlet.ThrowTerminatingError($errorRecord)\n\t\t}\n\n<############################################################################################\n# CreateErrorRecordHelper: This is a helper function used to create an ErrorRecord\n############################################################################################>\n\t\tfunction CreateErrorRecordHelper\n\t\t{\n\t\t\tparam\n\t\t\t(\n\t\t\t\t[string]\n\t\t\t\t$errorId,\n\n\t\t\t\t[string]\n\t\t\t\t$errorMessage,\n\n\t\t\t\t[System.Management.Automation.ErrorCategory]\n\t\t\t\t$errorCategory,\n\n\t\t\t\t[Exception]\n\t\t\t\t$exception,\n\n\t\t\t\t[object]\n\t\t\t\t$targetObject\n\t\t\t)\n\n\t\t\tif ($null -eq $exception)\n\t\t\t{\n\t\t\t\t$exception = New-Object System.IO.IOException $errorMessage\n\t\t\t}\n\n\t\t\t$errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $targetObject\n\t\t\treturn $errorRecord\n\t\t}\n\t\t#endregion Utility Functions\n\n\t\t$isVerbose = $psboundparameters.ContainsKey(\"Verbose\")\n\t\t$isConfirm = $psboundparameters.ContainsKey(\"Confirm\")\n\n\t\t$isDestinationPathProvided = $true\n\t\tif ($DestinationPath -eq [string]::Empty)\n\t\t{\n\t\t\t$resolvedDestinationPath = $pwd\n\t\t\t$isDestinationPathProvided = $false\n\t\t}\n\t\telse\n\t\t{\n\t\t\t$destinationPathExists = Test-Path -Path $DestinationPath -PathType Container\n\t\t\tif ($destinationPathExists)\n\t\t\t{\n\t\t\t\t$resolvedDestinationPath = GetResolvedPathHelper $DestinationPath $false $PSCmdlet\n\t\t\t\tif ($resolvedDestinationPath.Count -gt 1)\n\t\t\t\t{\n\t\t\t\t\t$errorMessage = ($LocalizedData.InvalidExpandedDirPathError -f $DestinationPath)\n\t\t\t\t\tThrowTerminatingErrorHelper \"InvalidDestinationPath\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $DestinationPath\n\t\t\t\t}\n\n\t\t\t\t# At this point we are sure that the provided path resolves to a valid single path.\n\t\t\t\t# Calling Resolve-Path again to get the underlying provider name.\n\t\t\t\t$suppliedDestinationPath = Resolve-Path -Path $DestinationPath\n\t\t\t\tif ($suppliedDestinationPath.Provider.Name -ne \"FileSystem\")\n\t\t\t\t{\n\t\t\t\t\t$errorMessage = ($LocalizedData.ExpandArchiveInValidDestinationPath -f $DestinationPath)\n\t\t\t\t\tThrowTerminatingErrorHelper \"InvalidDirectoryPath\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $DestinationPath\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$createdItem = New-Item -Path $DestinationPath -ItemType Directory -Confirm:$isConfirm -Verbose:$isVerbose -ErrorAction Stop\n\t\t\t\tif ($createdItem -ne $null -and $createdItem.PSProvider.Name -ne \"FileSystem\")\n\t\t\t\t{\n\t\t\t\t\tRemove-Item \"$DestinationPath\" -Force -Recurse -ErrorAction SilentlyContinue\n\t\t\t\t\t$errorMessage = ($LocalizedData.ExpandArchiveInValidDestinationPath -f $DestinationPath)\n\t\t\t\t\tThrowTerminatingErrorHelper \"InvalidDirectoryPath\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $DestinationPath\n\t\t\t\t}\n\n\t\t\t\t$resolvedDestinationPath = GetResolvedPathHelper $DestinationPath $true $PSCmdlet\n\t\t\t}\n\t\t}\n\n\t\t$isWhatIf = $psboundparameters.ContainsKey(\"WhatIf\")\n\t\tif (!$isWhatIf)\n\t\t{\n\t\t\t$preparingToExpandVerboseMessage = ($LocalizedData.PreparingToExpandVerboseMessage)\n\t\t\tWrite-Verbose $preparingToExpandVerboseMessage\n\n\t\t\t$progressBarStatus = ($LocalizedData.ExpandProgressBarText -f $DestinationPath)\n\t\t\tProgressBarHelper \"Expand-Archive\" $progressBarStatus 0 100 100 1\n\t\t}\n\t}\n\tPROCESS\n\t{\n\t\tswitch ($PsCmdlet.ParameterSetName)\n\t\t{\n\t\t\t\"Path\"\n\t\t\t{\n\t\t\t\t$resolvedSourcePaths = GetResolvedPathHelper $Path $false $PSCmdlet\n\n\t\t\t\tif ($resolvedSourcePaths.Count -gt 1)\n\t\t\t\t{\n\t\t\t\t\t$errorMessage = ($LocalizedData.InvalidArchiveFilePathError -f $Path, $PsCmdlet.ParameterSetName, $PsCmdlet.ParameterSetName)\n\t\t\t\t\tThrowTerminatingErrorHelper \"InvalidArchiveFilePath\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $Path\n\t\t\t\t}\n\t\t\t}\n\t\t\t\"LiteralPath\"\n\t\t\t{\n\t\t\t\t$resolvedSourcePaths = GetResolvedPathHelper $LiteralPath $true $PSCmdlet\n\n\t\t\t\tif ($resolvedSourcePaths.Count -gt 1)\n\t\t\t\t{\n\t\t\t\t\t$errorMessage = ($LocalizedData.InvalidArchiveFilePathError -f $LiteralPath, $PsCmdlet.ParameterSetName, $PsCmdlet.ParameterSetName)\n\t\t\t\t\tThrowTerminatingErrorHelper \"InvalidArchiveFilePath\" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $LiteralPath\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tValidateArchivePathHelper $resolvedSourcePaths\n\n\t\tif ($pscmdlet.ShouldProcess($resolvedSourcePaths))\n\t\t{\n\t\t\t$expandedItems = @()\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\t# StopProcessing is not avaliable in Script cmdlets. However the pipleline execution\n\t\t\t\t# is terminated when ever 'CTRL + C' is entered by user to terminate the cmdlet execution.\n\t\t\t\t# The finally block is executed whenever pipleline is terminated.\n\t\t\t\t# $isArchiveFileProcessingComplete variable is used to track if 'CTRL + C' is entered by the\n\t\t\t\t# user.\n\t\t\t\t$isArchiveFileProcessingComplete = $false\n\n\t\t\t\t# The User has not provided a destination path, hence we use '$pwd\\ArchiveFileName' as the directory where the\n\t\t\t\t# archive file contents would be expanded. If the path '$pwd\\ArchiveFileName' already exists then we use the\n\t\t\t\t# Windows default mechanism of appending a counter value at the end of the directory name where the contents\n\t\t\t\t# would be expanded.\n\t\t\t\tif (!$isDestinationPathProvided)\n\t\t\t\t{\n\t\t\t\t\t$archiveFile = New-Object System.IO.FileInfo $resolvedSourcePaths\n\t\t\t\t\t$resolvedDestinationPath = Join-Path -Path $resolvedDestinationPath -ChildPath $archiveFile.BaseName\n\t\t\t\t\t$destinationPathExists = Test-Path -LiteralPath $resolvedDestinationPath -PathType Container\n\n\t\t\t\t\tif (!$destinationPathExists)\n\t\t\t\t\t{\n\t\t\t\t\t\tNew-Item -Path $resolvedDestinationPath -ItemType Directory -Confirm:$isConfirm -Verbose:$isVerbose -ErrorAction Stop | Out-Null\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tExpandArchiveHelper $resolvedSourcePaths $resolvedDestinationPath ([ref]$expandedItems) $Force $isVerbose $isConfirm\n\n\t\t\t\t$isArchiveFileProcessingComplete = $true\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\t# The $isArchiveFileProcessingComplete would be set to $false if user has typed 'CTRL + C' to\n\t\t\t\t# terminate the cmdlet execution or if an unhandled exception is thrown.\n\t\t\t\tif ($isArchiveFileProcessingComplete -eq $false)\n\t\t\t\t{\n\t\t\t\t\tif ($expandedItems.Count -gt 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t# delete the expanded file/directory as the archive\n\t\t\t\t\t\t# file was not completly expanded.\n\t\t\t\t\t\t$expandedItems | ForEach-Object { Remove-Item $_ -Force -Recurse }\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction Write-LocalMessage\n{\n    [CmdletBinding()]\n    Param (\n        [string]$Message\n    )\n\n    if (Test-Path function:Write-PSFMessage) { Write-PSFMessage -Level Important -Message $Message }\n    else { Write-Host $Message }\n}\n#endregion Utility Functions\n\ntry\n{\n\t[System.Net.ServicePointManager]::SecurityProtocol = \"Tls12\"\n\n\tWrite-LocalMessage -Message \"Downloading repository from '$($BaseUrl)/archive/$($Branch).zip'\"\n\tInvoke-WebRequest -Uri \"$($BaseUrl)/archive/$($Branch).zip\" -UseBasicParsing -OutFile \"$($env:TEMP)\\$($ModuleName).zip\" -ErrorAction Stop\n\t\n\tWrite-LocalMessage -Message \"Creating temporary project folder: '$($env:TEMP)\\$($ModuleName)'\"\n\t$null = New-Item -Path $env:TEMP -Name $ModuleName -ItemType Directory -Force -ErrorAction Stop\n\t\n\tWrite-LocalMessage -Message \"Extracting archive to '$($env:TEMP)\\$($ModuleName)'\"\n\tExpand-Archive -Path \"$($env:TEMP)\\$($ModuleName).zip\" -DestinationPath \"$($env:TEMP)\\$($ModuleName)\" -ErrorAction Stop\n\t\n\t$basePath = Get-ChildItem \"$($env:TEMP)\\$($ModuleName)\\*\" | Select-Object -First 1\n\tif ($SubFolder) { $basePath = \"$($basePath)\\$($SubFolder)\" }\n\t\n\t# Only needed for PS v5+ but doesn't hurt anyway\n\t$manifest = \"$($basePath)\\$($ModuleName).psd1\"\n\t$manifestData = Invoke-Expression ([System.IO.File]::ReadAllText($manifest))\n\t$moduleVersion = $manifestData.ModuleVersion\n\tWrite-LocalMessage -Message \"Download concluded: $($ModuleName) | Branch $($Branch) | Version $($moduleVersion)\"\n\t\n\t# Determine output path\n\t$path = \"$($env:ProgramFiles)\\WindowsPowerShell\\Modules\\$($ModuleName)\"\n\tif ($doUserMode) { $path = \"$(Split-Path $profile.CurrentUserAllHosts)\\Modules\\$($ModuleName)\" }\n\tif ($PSVersionTable.PSVersion.Major -ge 5) { $path += \"\\$moduleVersion\" }\n\t\n\tif ((Test-Path $path) -and (-not $Force))\n\t{\n\t\tWrite-LocalMessage -Message \"Module already installed, interrupting installation\"\n\t\treturn\n\t}\n\t\n\tWrite-LocalMessage -Message \"Creating folder: $($path)\"\n\t$null = New-Item -Path $path -ItemType Directory -Force -ErrorAction Stop\n\t\n\tWrite-LocalMessage -Message \"Copying files to $($path)\"\n\tforeach ($file in (Get-ChildItem -Path $basePath))\n\t{\n\t\tMove-Item -Path $file.FullName -Destination $path -ErrorAction Stop\n\t}\n\t\n\tWrite-LocalMessage -Message \"Cleaning up temporary files\"\n\tRemove-Item -Path \"$($env:TEMP)\\$($ModuleName)\" -Force -Recurse\n\tRemove-Item -Path \"$($env:TEMP)\\$($ModuleName).zip\" -Force\n\t\n\tWrite-LocalMessage -Message \"Installation of the module $($ModuleName), Branch $($Branch), Version $($moduleVersion) completed successfully!\"\n}\ncatch\n{\n\tWrite-LocalMessage -Message \"Installation of the module $($ModuleName) failed!\"\n\t\n\tWrite-LocalMessage -Message \"Cleaning up temporary files\"\n\tRemove-Item -Path \"$($env:TEMP)\\$($ModuleName)\" -Force -Recurse\n\tRemove-Item -Path \"$($env:TEMP)\\$($ModuleName).zip\" -Force\n\t\n\tthrow\n}"
  },
  {
    "path": "library/d365fo.tools/d365fo.tools/Class1.cs",
    "content": "﻿using System;\n\nnamespace d365fo.tools\n{\n    public class Class1\n    {\n    }\n}\n"
  },
  {
    "path": "library/d365fo.tools/d365fo.tools/d365fo.tools.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>net4.5.2</TargetFramework>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\n    <OutputPath>..\\..\\..\\d365fo.tools\\bin</OutputPath>\n    <DocumentationFile>..\\..\\..\\d365fo.tools\\bin\\d365fo.tools.xml</DocumentationFile>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Release)|$(Platform)'=='Debug|AnyCPU'\">\n    <OutputPath>..\\..\\..\\d365fo.tools\\bin</OutputPath>\n    <DocumentationFile>..\\..\\..\\d365fo.tools\\bin\\d365fo.tools.xml</DocumentationFile>\n  </PropertyGroup>\n  \n  <PropertyGroup>\n    <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>\n  </PropertyGroup>\n\n</Project>\n"
  },
  {
    "path": "library/d365fo.tools/d365fo.tools.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.27130.2010\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{361C84EE-64AA-4E88-94D8-2104C3670C0C}\") = \"d365fo.tools\", \"d365fo.tools\\d365fo.tools.csproj\", \"{426BC3CD-F2B9-4B1E-95EF-C5299426A72A}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{426BC3CD-F2B9-4B1E-95EF-C5299426A72A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{426BC3CD-F2B9-4B1E-95EF-C5299426A72A}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{426BC3CD-F2B9-4B1E-95EF-C5299426A72A}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{426BC3CD-F2B9-4B1E-95EF-C5299426A72A}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {3A54BDDB-A20F-4A50-9C82-E62C507D0415}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "wiki/Azure-DevOps-Build-Configuration.md",
    "content": "## **Prerequisites**\nYou will need a Personal Access Token configured in your github account. Read this [guide](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/) to obtain that.\n\n## ﻿**Configure Github Access**\n1. Navigate to your Azure DevOps project\n2. Click on the **\"Project settings\"** icon in the bottom left corner of the page\n\n[[images/image-e2513b65-f1db-4dad-a630-0e2ae6510eb9.png]]\n\n3. Select the **\"Service connections\"** menu option, under the **\"Pipelines\"** section in the new navigation tile on the left\n4. Select **\"Github\"** from the **\"New service connection\"** dropdown list\n\n[[images/image-42be014d-3dab-49a4-827b-41ba6385b913.png]]\n\n5. Select the **\"Personal access token\"** option in the **\"Choose authorization\"** configuration\n6. Fill in a desired **name** for this connection that you are creating in the **\"Connection Name\"** configuration\n7. Fill in your token that you have created on Github in the **\"Token\"** configuration\n\n[[images/image-99ecf271-0fbd-4b8d-9133-970992f628b2.png]]\n\n8. Validate that the **\"Service Connection\"** is created as desired and go back to your Azure DevOps project start page\n\n## **Setup the build pipeline**\n\n1. Select the **\"Pipelines\"** menu option in the navigation on the left\n2. Select the **\"Builds\"** menu option that is revealed under the **\"Pipelines\"** section in the navigation on the left\n3. Click the **\"+ New\"** iceon and select the **\"New build pipeline\"** from the dropdown\n\n[[images/image-424819b5-687c-4b5d-8558-9953d7912ab1.png]]\n\nOr if you never did create a build pipeline it will just show you a empty page with just one button to click\n\n[[images/image-c3d3a98c-42bd-4864-b007-8402f94a8d10.png]]\n\n4. You have to select the **\"Github\"** option and validate that it selects the current **\"Service Connection\"** created earlier\n5. Select the github repository you want to build\n6. Select the default branch that the build pipeline should build when you initiate a manuel build\n    - **\"master\"** is the normal default\n7. Click continue when ready\n\n[[images/image-b86b0ca1-9123-4e35-9d91-3079b9a70658.png]]\n\n8. Select the **\"Empty job\"** option in the very top of the page\n\n[[images/image-7a660f10-5970-4246-bb0c-053e24c67689.png]]\n\n9. Select the new Agent job 1 and click on the + sign\n10. Search for PowerShell and add 2 x PowerShell tasks\n\n[[images/image-00b1392f-9f4c-4b62-96d8-ba9e67a4e92d.png]]\n\n11. Search for Publish Test Results and add only 1\n\n[[images/image-7cda2c2c-0276-45de-b48a-a250bfafe0b9.png]]\n\n12. Validate that you have **2** PowerShell tasks and **1** Publish Test Results\n\n[[images/image-a520bea2-d107-4df4-9582-534e98563aaa.png]]\n\n13. Select the first PowerShell task, name it **\"Prerequisites\"**\n14. Fill in **\"build/vsts-prerequisites.ps1\"** into the **\"Script Path\"**\n\n[[images/image-77dce872-0c56-440a-8103-5b1b1af5be05.png]]\n\n15. Select the second PowerShell task, name it **\"Validate\"**\n16. Fill in **\"build/vsts-validate.ps1\"** into the **\"Script Path\"**\n\n[[images/image-7bfbab7d-5253-4ee5-8514-b3ff67e8364b.png]]\n\n17. Select the Publish Test Results and change the **\"Test result format\"** from **\"JUnit\"** to **\"NUnit\"**\n18. Expand the **\"Control Options\"** section and change the **\"Run this task\"** value from **\"Only when all previous tasks have succeeded\"** to **\"Even if a previous task has failed, even if the build was canceled\"**\n\n[[images/image-a46e25f0-f4bd-446d-9942-97bcc614b4f4.png]]\n\n19. When ready click on the **\"Save & queue\"** button in the top menu and select the **\"Save\"** option from the dropdown menu\n\n[[images/image-3c49f8ae-a868-46f7-8fa2-402e58cc341d.png]]\n\n20. Go back to the build pipeline overview and **\"Queue\"** a new build\n21. Accept the default values from the popup\n\n[[images/image-9482e53d-e2fc-4129-894d-c6881a23358d.png]]\n\n22. Once the build is done and error free, you can continue the configuration of your github repository and branch protection"
  },
  {
    "path": "wiki/Branching.md",
    "content": "## **Branching strategy**\n\nWe encourage the use of features/bug fixes branches when working against the d365fo.tools repo. Read more about it [here](https://docs.microsoft.com/en-us/azure/devops/repos/git/git-branching-guidance?view=vsts)\n\nOne of the benefits of having a feature branch is that if you want to submit multiple PR's against the central repository and you have to rework different parts of any PR, things are separated. When you push your changes to your branch, things get picked up automatically and the check pipeline will execute currently once again.\n\n## **Create a new branch from the desktop client**\n\n1. Make sure that you have selected your local repository\n2. Make sure that you have selected the master branch\n\n[[images/Branch.001.png]]\n\n3. Click on the **master** branch icon in the top\n4. Click on the **New branch** button in the drop down menu\n\n[[images/Branch.002.png]]\n\n5. Fill in the name of the desired branch\n6. Click on **Create branch** when ready\n    - We recommend that you provide a meaningful name, without spaces\n\n[[images/Branch.003.png]]\n\n7. Make sure that the branch was created and your local repository is switched to that\n\n[[images/Branch.004.png]]\n\n8. Do your magic and commit stuff to your branch\n9. When you are ready to create a pull request (PR), simply click on the **Publish branch** button in the top menu\n\n[[images/Branch.005.png]]\n\n10. To create a PR, simply click on the **Branch** menu item in the very top of the window and click on the **Create pull request** option\n\n[[images/Branch.006.png]]\n\n11. Your default browser will now load and go to github\n12. Make sure that you compared the branch against the **master** branch in the d365fo.tools repository\n\n[[images/Branch.007.png]]"
  },
  {
    "path": "wiki/Building-tools.md",
    "content": "When you contribute to the d365fo.tools project you will quickly learn that we have several validation steps that might throw an error when you are creating PR's against the repository.\n\nThese validations are checked when you create a pull request. The checks are done by GitHub Actions and are defined in the [build.yml](https://github.com/d365collaborative/d365fo.tools/blob/master/.github/workflows/build.yml) file. The GitHub Action will run the PowerShell scripts in the [build](https://github.com/d365collaborative/d365fo.tools/tree/master/build) folder of the repository starting with `vsts-`.\n\nFor some of the checks, we have created PowerShell scripts that can be used to automatically make the changes needed to pass the validation. You can run these scripts locally on your machine to make the changes needed before you create a pull request. They are also available as a GitHub Action defined in the [update-generated-text.yml](https://github.com/d365collaborative/d365fo.tools/blob/master/.github/workflows/update-generated-text.yml). If you have your own fork of the repository, you can use this action to automatically update the generated files in your pull requests.\n\nTo run the scripts locally, follow the instructions below.\n\n## **Prerequisites**\n* PSModuleDevelopment (PowerShell module to aid with development)\n   * `Install-Module PSModuleDevelopment -Force -Confirm:$false`\n* platyPS (PowerShell module to aid with documentation for modules)\n   * `Install-Module platyPS -Force -Confirm:$false`\n\n## **Format Comment Based help**\nWe try to keep the formatting of the Comment Based Help the same across every contributor. This is done by the [Format-CommentBasedHelp.ps1](https://github.com/d365collaborative/d365fo.tools/tree/master/build/format-commentbasedhelp.ps1) script. If you want to find out more about comment based help, take a look at [about Comment Based Help](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comment_based_help).\n\n## **Generate-ParameterUnitTests**\nWe try to mitigate the drifting changes that might get introduced when multiple people contribute to the same project. We also try to ensure that the parameters do not change **without** us knowing about it. This helps us update the examples inside the Comment Based Help and therefor the user base. This is done by the [Generate-ParameterUnitTests.ps1](https://github.com/d365collaborative/d365fo.tools/tree/master/build/generate-parameterunittests.ps1) script. This script will generate a new test file for each command in the module, using the `Invoke-PSMDTemplate` cmdlet of [PSModuleDevelopment](https://github.com/PowershellFrameworkCollective/PSModuleDevelopment). The tests will check a list of best practices.\n\n## **Update-Docs**\nWhenever we release a new version of the module, we push the updated markdown files used for documentation, to make sure that users can lookup parameter names and parameterset specification. This is done by the [Update-Docs.ps1](https://github.com/d365collaborative/d365fo.tools/tree/master/build/update-docs.ps1) script. The markdown files are created from the Comment Based Help in the module. The `New-MarkdownHelp` cmdlet of [platyPS](https://learn.microsoft.com/en-us/powershell/utility-modules/platyps/overview) is used to create the markdown files.\n\n## **Generate-FindCommandIndex**\nThe [Find-D365Command](Find-D365Command.md) is used to find commands in the module. It acts faster than the built-in Get-Help cmdlet, but it requires a file to be updated whenever a new command is added to the module. This script will update the file with the new command. Find the script in the build folder of the repository: [Generate-FindCommandIndex.ps1](https://github.com/d365collaborative/d365fo.tools/tree/master/build/Generate-FindCommandIndex.ps1).\n\n## **Closing notes**\nThe reason why we keep these steps manual for the time being is to make sure that nothing gets updated without we either knowing about it or without us making a \"decision\" to update these things."
  },
  {
    "path": "wiki/Call-Internal-Functions.md",
    "content": "# Call internal functions\n\nd365fo.tools has a number of internal functions that are used by the cmdlets. These functions are not intended to be used directly by the user and as such cannot be called directly. However, for troubleshooting purposes or when developing cmdlets, it can be useful to call these functions directly.\n\n> ⚠️ **Warning** If you follow these instructions to call internal functions, we assume you know what you are doing and have taken precautions against an internal function call going wrong.\n\n## Dot source the internal function\n\nTo call an internal function, you need to [dot source](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scripts?view=powershell-5.1#script-scope-and-dot-sourcing) the function. This is done by using the `.` operator followed by the path to the function. \n\nThe path to the function consists of 3 parts:\n1. **The path to the module**: If you have installed the module, you can use the following PowerShell command to get the path to the module:\n    ```powershell\n    Split-Path $(Get-Module d365fo.tools -ListAvailable | Select-Object -First 1).Path\n    ```\n    This will return the path to the module, which is typically something like `C:\\Program Files\\WindowsPowerShell\\Modules\\d365fo.tools\\` followed by a version number.\n2. **The path to the function**: Within the module, the internal functions are located in the `internal\\functions` folder.\n3. **The file name of the function**: The file name of the function is the name of the function you want to call, followed by `.ps1`.\n\nFor example, to dot source the internal function `Invoke-Process` you would use a command similar to the following:\n```\n. 'C:\\Program Files\\WindowsPowerShell\\Modules\\d365fo.tools\\0.7.9\\internal\\functions\\Invoke-Process.ps1'\n```\n\n## Call the internal function\n\nOnce you have dot sourced the internal function, you can call it as you would any other function. For example, to call the `Invoke-Process` function, you would use a command similar to the following:\n\n```powershell\nInvoke-Process -Path 'C:\\Temp\\Program.exe' -Params '/help'\n```\n\n## Dependencies\n\nInternal functions may have dependencies on other internal functions, cmdlets or settings. If you are calling an internal function that has dependencies, you will need to dot source and initialize the dependencies as well.\n\nThis may require calling the function multiple times. Each time, the error messages should help you identify which dependencies are missing.\n\nFor example, the `Invoke-Process` function has the following dependencies:\n- internal function `Invoke-TimeSignal`\n- internal function `Test-PathExists`\n- setting `$Script:TimeSignals`\n\nSo to fully load the `Invoke-Process` function, you would use the following script:\n\n```powershell\n. 'C:\\Program Files\\WindowsPowerShell\\Modules\\d365fo.tools\\0.7.9\\internal\\functions\\Invoke-TimeSignal.ps1'\n. 'C:\\Program Files\\WindowsPowerShell\\Modules\\d365fo.tools\\0.7.9\\internal\\functions\\Test-PathExists.ps1'\n. 'C:\\Program Files\\WindowsPowerShell\\Modules\\d365fo.tools\\0.7.9\\internal\\functions\\Invoke-Process.ps1'\n$Script:TimeSignals = @{}\n```\n\n> ℹ️ **Note** The dependencies of an internal function may have dependencies of their own."
  },
  {
    "path": "wiki/Calling-the-Table-Browser-from-the-browser.md",
    "content": "**You want to be able to call the table browser in an easy way**\n\n```\nInvoke-D365TableBrowser -TableName SalesTable -Company \"USMF\"\n```\n*This will start a web browser and have it call the SysTableBrowser menu item with the SalesTable name of the table you want to see data from and only execute it against the USMF company*\n\n**Small teaser for the combination of Get-D365Table and Invoke-D365TableBrowser**\n\n```\nGet-D365Table -Name CustTable,CustTrans | Invoke-D365TableBrowser -Company USMF\n```\n*You want to start the table browser for **both** CustTable & CustTrans, against the USMF company*"
  },
  {
    "path": "wiki/Configuration.md",
    "content": "Many d365fo.tools cmdlets use default values for their parameters. This makes the cmdlets easier to use, since the user only has to care about the parameters that need to be specified for their use case. But you may wonder what the default values are and how the module determines them.\n\n# An example\n\nFor example, the [Get-D365Module](https://github.com/d365collaborative/d365fo.tools/blob/master/d365fo.tools/functions/get-d365module.ps1) cmdlet has a `-PackageDirectory` parameter. The documentation for the parameter says *Normally it is located under AOSService directory in \"PackagesLocalDirectory\" - Default value is fetched from the current configuration on the machine*. Looking at the code of the cmdlet, it specifies the parameter like this: `[string] $PackageDirectory = $Script:PackageDirectory`.\n\nWe will come back to this example in the following sections to explain how the default value is determined.\n\n# The script scope\n\nYou may have noticed that the default value for the `-PackageDirectory` parameter is `$Script:PackageDirectory`. The `$Script:` part is a scope specifier. Scopes are a common concept in many programming languages to define the visibility of variables. For PowerShell, scopes are documented in the [about_Scopes](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes) help topic.\n\nFor the purpose of the d365fo.tools module, the script scope lets us define variables that are available to all cmdlets in the module. This is useful for variables that are used by many cmdlets, like the `-PackageDirectory` variable. Note that variables with this scope are not available to the user of the module, only to the cmdlets in the module. So unfortunately, there is no easy way for users to tell what the default value of parameters like `-PackageDirectory` is, because they cannot access the script scope.\n\n# Setting the default values\n\nThe values of the variables in the script scope are set in several internal scripts that get executed when the module is imported. You can see this in the [postimport.ps1](https://github.com/d365collaborative/d365fo.tools/blob/master/d365fo.tools/internal/scripts/postimport.ps1) script, where the [variables.ps1](https://github.com/d365collaborative/d365fo.tools/blob/master/d365fo.tools/internal/scripts/variables.ps1) script is called. This script sets the default values for many variables in the module. \n\n## It depends\n\nYou will note that some variables get assigned a fixed value (like `$Script:WebConfig = \"web.config\"` for the variable that stores the name of the web.config file). Others get their value assigned by other means, which means there is no one way to determine the default value of a variable. But the variables.ps1 script is a good place to start looking.\n\nFor the `-PackageDirectory` variable, it uses `$Script:PackageDirectory = $environment.Aos.PackageDirectory`. So for this particular variable, there is another layer of indirection before its value can be determined. The `$environment` variable is set by a call to `Get-ApplicationEnvironment`, which is an internal function not available outside of the module. However, that internal function is used by the `Get-D365EnvironmentSettings` cmdlet, which is available to the user. So the user can determine the value of the `-PackageDirectory` variable by calling `Get-D365EnvironmentSettings` and looking at the `Aos.PackageDirectory` property of the returned object.\n\n```powershell\t\n$environmentSettings = Get-D365EnvironmentSettings\n$environmentSettings.Aos.PackageDirectory\n```\n\nThis of course requires advanced knowledge of the inner workings of the module and is not intended for regular use. But it serves as an example of how the default values of the variables in the module are determined.\n\n# Configurable default values\n\nYou may have noticed that there are several calls to internal functions in the variables.ps1 script. The ones discussed here start with `Update-` and end with `Variables`, like `Update-ModuleVariables`. These functions do the same as the variables.ps1 script, but have outsourced some of the variable value initialization to these functions. You can tell from the name of the function that they cover certain functional areas of the module. For example, `Update-AzureStorageVariables` sets the default values for variables related to Azure Storage.\n\nThe common theme for these variables is that they are based on configuration values. The variables discussed so far are usually static and without a need by a user to change them. But there are also variables that are based on configuration values that the user can set. With the exception of `Update-ModuleVariables`, those configuration value are defined by cmdlets of the module. For example, the `Update-AzureStorageVariables` function uses the values set by the `Add-D365AzureStorageConfig` and `Set-D365ActiveAzureStorageConfig` cmdlets.\n\nAnother important thing to note is that the configuration values are persisted between sessions. This means that the user only has to set the configuration values once, and they will be used as default values for the variables in all future sessions of the module.\n\nThis also applies to the `Update-ModuleVariables` function, but the configuration values are not set by the user, but by the module itself. The configuration values are specified in the [configuration.ps1](https://github.com/d365collaborative/d365fo.tools/blob/master/d365fo.tools/internal/configurations/configuration.ps1) script. To understand how those configurations work, we first need to learn about the PSFramework module.\n\n## PSFramework\n\nA lot of the general structure and functionality of d365fo.tools is provided by the PSFramework module. This module provides a lot of functionality for building advanced PowerShell modules, and one of the features it provides is the ability to define a configuration for a module. This is part of the configuration system of PSFramework. You can learn more about it here: [The Configuration System](https://psframework.org/documentation/documents/psframework/configuration.html).\n\nYou can see in the `configurations.ps1` script how the `Set-PSConfig` cmdlet of PSFramework is used to define the configuration for the d365fo.tools module. The configuration is then used by the `Update-ModuleVariables` function to set the default values for several variables in the script scope.\n\nHowever, not all configurations values are exposed as variables in the script scope. Some are also taken directly from the PSFramework configuration with the `Get-PSFConfig` cmdlet."
  },
  {
    "path": "wiki/Configure-Azure-Logic-App.md",
    "content": "### **Intro**\nSo you want to be able to notify someone when a cmdlet is done running? You read about the magical Invoke-D365LogicApp cmdlet?\n\nThis will guide you through on how to configure everything inside the Azure Portal.\n\n### **Requirements**\nYou will need the following **before** you can start:\n1. An active Azure subscription\n2. An Office365 user account (Azure Active Directory)\n   - Email license assigned\n\n### **Prepare**\nDownload a copy of the file [AzureLogicApp-Template.json](https://raw.githubusercontent.com/d365collaborative/d365fo.tools/master/AzureLogicApp-Template.json)\n and save if on your computer.\n\n### **Implementation**\n1. Visit https://portal.azure.com\n2. Click **\"Create a resource\"**\n \n[[images/AzureLogicApp.001.png]]\n\n3. Search for **\"Template\"** and select the **\"Template deployment\"** option from the results\n\n[[images/AzureLogicApp.002.png]]\n\n4. Click \"Create\"\n\n[[images/AzureLogicApp.003.png]]\n\n5. Click **\"Build your own template in the editor\"**\n\n[[images/AzureLogicApp.004.png]]\n\n6. Click **\"Load file\"**\n\n[[images/AzureLogicApp.005.png]]\n\n7. Locate the **\"AzureLogicApp-Template.json\"* file that you downloaded earlier.\n\n[[images/AzureLogicApp.006.png]]\n\n8. After the import of the json file, click on the **\"Variables\"** and select the **\"ConnectionName\"**. Change the name of the connection in the editor if you want - it doesn't have any real impact on the solution.\n\n[[images/AzureLogicApp.007.png]]\n\n9. Fill in all the details that are necessary, click the **\"I agree to the terms and conditions stated above\"** checkbox and click on **\"Purchase\"**\n\n[[images/AzureLogicApp.008.png]]\n\n10. Wait for the deployment to complete. Click on the notification icon in the top right corner.\n\n[[images/AzureLogicApp.009.png]]\n\n11. Click on **\"Resource groups\"** and search for the resource group you filled in during deployment. Click the resource group to continue.\n\n[[images/AzureLogicApp.011.png]]\n\n12. Click on **\"NotifyWhenDone\"** (Logic App) - remember that you could have changed the name during deployment.\n\n[[images/AzureLogicApp.012.png]]\n\n13. Click **\"Edit\"**\n\n[[images/AzureLogicApp.013.png]]\n\n14. Click on the **\"Connections\"** bar with the **Outlook** icon and the yellow/orange exclamation mark. Click on **\"Invalid Connection\"**.\n\n[[images/AzureLogicApp.014.png]]\n\n15. Select an account of yours that is an AAD and have an email license.\n\n[[images/AzureLogicApp.015.png]]\n\n16. Click on the connection that has a blue checkmark to the left.\n\n[[images/AzureLogicApp.016.png]]\n\n17. Validate that things look like they should.\n\n[[images/AzureLogicApp.017.png]]\n\n18. Save the Logic App.\n19. Click **\"Edit\"** once more.\n20. Click **\"When a Http Request is received\"** and click on the copy to clipboard button next to the URL.\n\n[[images/AzureLogicApp.018.png]]"
  },
  {
    "path": "wiki/Deprecation-guidelines.md",
    "content": "As part of the application lifecycle management, cmdlets may become deprecated. In that case, the documentation of the cmdlet should be updated to inform about the deprecation and possible alternatives. After a 6 month period, the cmdlet shoud be removed.\n\nTo track the deprecation and removal of a cmdlet, an issue should be created that should be labeled [deprecation](../labels/deprecation)."
  },
  {
    "path": "wiki/Do-And-Do-Not.md",
    "content": "# Writing Documentation:\n\n* [If a a function accepts pipeline input, there should at least be one example that shows it being used that way.](https://trello.com/c/Aax7fm9M/52-if-a-a-function-accepts-pipeline-input-there-should-at-least-be-one-example-that-shows-it-being-used-that-way)\n\n\n* [In Examples, we need to ensure that no unneeded quotes in parameter values and discourage useless quotes.](https://trello.com/c/rXl5jFf2/19-code-verbosity-quotes-when-not-required-semicolons-anything-else-that-doesnt-fit-in-name-usage)\n\n# Writing Code:\n\n* [Prefer dot notation over `Select -ExpandProperty`.](https://trello.com/c/p9c6clqP/59-using-get-childitem-fullname-or-get-childitem-select-expandproperty-fullname)\n  * eg. `(Get-ChildItem).FullName`\n    \n* [Try to return a useful object for the use case and dont try to overtly customize standard .NET types unless needed.](https://trello.com/c/9qcfNYbo/60-do-we-need-to-consistently-output-the-same-type-of-objects-pscustomobject-vs-datatable-vs-out-dbadatatable-is-nice-but-has-a-per)\n\n* [When supressing output using null types, use chained assignment.](https://trello.com/c/zraES2j3/43-null-name-f-some-string-vs-name-f-some-string-out-null)\n  * eg. `$null = $result = Command-WhichProducedOutputWhenAssigned`\n\n* [Avoid Write-Output, instead return useful objects closest to the value type of the target](https://trello.com/c/fWiKta1O/15-do-we-write-output-immediately-instead-of-gathering-results-and-waiting-until-the-end-of-the-function-to-return-them)\n\n* [If you need to initialize a value, use $null and avoid values such as a blank string](https://trello.com/c/pvvSrLw7/38-use-null-instead-of-unless-otherwise-required-ie-in-a-pscustomobject-database-vs-database-null)\n\n* [Semicolons are discouraged unless absolutely necessary, consider breaking your statements on multiple lines](https://trello.com/c/rXl5jFf2/19-code-verbosity-quotes-when-not-required-semicolons-anything-else-that-doesnt-fit-in-name-usage):\n  * eg. Constructing a pscustomobject from a hash table, also useful for cheap object creation:\n\n    ```\n    [pscustomobject]@{\n        ServerName = $servername\n        IsEnabled = $true\n    }\n    ```\n* [For encapsulating input please use double quotes in PowerShell any output should have bracket escaped values.](https://trello.com/c/rXl5jFf2/19-code-verbosity-quotes-when-not-required-semicolons-anything-else-that-doesnt-fit-in-name-usage)\n\n* [Avoid continuation marks (backticks) in code if at all possible.](https://trello.com/c/Xja13fUY/20-do-we-have-guidelines-for-consistent-use-of-one-liners)\n\n* [Do not indent BEGIN, PROCESS, or END in advanced functions.](https://trello.com/c/yaHYu157/7-how-to-properly-space-for-begin-process-end-0-spaces-from-the-left-line-spacing-can-be-ambiguous-when-using-single-line-scriptbl)\n\n* [Casing follows PowerShell community recommendations](https://trello.com/c/MxprMJhU/5-casing-of-if-else-continue-return-begin-process-end):\n  \n  * Lower:\n    * Language keyword (try, catch, foreach)\n    * Process block keyword (begin, process, end)\n\n  * Pascal:\n    * Comment help keywords (.Example, .Synopsis)\n    * Package or modules \n    * Class\n    * Exception\n    * Global variables\n        \n  * Camel Case:\n    * Local variables ($localArgument)\n    \n  * There may be rare cases in which features do not work without required casing, in those cases ignore these recommendations.\n\n* [When choosing names and methods for booleans, consider using a more descriptive name than \"Enabled\" or \"IsEnabled\", instead add additional descriptive information such as \"IsAdEnabled\" or \"IsSqlEnabled\"](https://trello.com/c/qfXBDHm8/39-isenabled-vs-status)\n\n* The defacto naming convention for any command is ApprovedVerb-D365*\n\n* [Use one space after a bracket.](https://trello.com/c/Lb6rUOD4/37-how-should-spaces-must-come-after-brackets-where-object-whatever-eq-whatever)\n\n* [Use `-Force` instead of `-Confirm:$False`](https://trello.com/c/OYaUyhMO/27-we-did-discuss-this-tweeted-with-msft-about-it-got-mixed-reviews-one-tweet-in-particular-lined-up-with-the-way-that-we-use-force)\n\n* [Open braces on the same line, Closing braces always on their own line.](https://trello.com/c/20GTHsQM/63-when-creating-script-blocks-create-a-bracket-on-new-line-http-www-poll-maker-com-results924522x3e366fd2-38)\n\n* [There is no need to write empty keywords in advanced functions if they are not used (`begin`,`process`,`end`)](https://trello.com/c/NYtu5JUJ/40-do-we-want-to-use-an-empty-begin-and-empty-end-in-advanced-functions-when-we-have-no-code-to-place-in-the-script-block-please-le)\n\n**Note:** This entire page is deeply inspired by the work done over in the [dbatool.io](https://github.com/sqlcollaborative/dbatools) module. Pay them a visit and learn from the very same people as we did."
  },
  {
    "path": "wiki/Exception-handling.md",
    "content": "You may have noticed that the d365fo.tools cmdlets rarely throw exceptions. In fact, most cmdlets are written in such a way that exceptions are caught and a warning message is displayed instead.\n\nWhile this is the preferred approach when using the d365fo.tools in an interactive way (i.e. a users enters commands one by one in a PowerShell console), it can cause issues in other situations.\n\nIf for example you want to write a script that call severals cmdlets, the script should probably stop when one call runs into an issue. But instead, the script just shows a warning and continues executing the other calls.\n\n# How to stop execution of the cmdlets in case of a warning?\n\nThe simplest way to change the default behavior is to tell PowerShell that it should stop executing in case of a warning. This can be done by setting the value of a preference variable:\n```\n$WarningPreference=\"Stop\"\n```\n\nThis will change the behavior of all PowerShell commands that are executed after this variable has been set for the remainder of the PowerShell session.\n\nIf you want to restore the default behavior, run the following command or start a new PowerShell session:\n```\n$WarningPreference=\"Continue\"\n```\n\nTo learn more about preference variables, run the following command or visit [about_Preference_Variables](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables).\n```\nGet-Help About_Preference_Variables\n```\n\n# How to throw exceptions?\n\nWhile stopping in case of warnings will cover many situations, sometimes you might prefer getting a real exception so you can implement your own exception handling. \n\nTo cover those situations, the d365fo.tools provide a cmdlet to activate exceptions: `Enable-D365Exception`\n\nBy calling this cmdlet at the start of a PowerShell session (or at the beginning of a script), subsequent calls to other cmdlets of the module will throw an exception in case of an issue.\n\nHowever, note that only cmdlets with the `-EnableException` parameter support this type of exception handling.\n\nTo disable throwing exceptions, call the `Disable-D365Exception` cmdlet.\n\n## What does the -EnableException parameter do?\n\nYou may have noticed that some cmdlets provide a `-EnableException` switch parameter that does not seem to change how the cmdlet behaves. This is because this parameter only works in combination with the `Enable-D365Exception` cmdlet. \n\nYou would not add this parameter explicitely to your commands. Rather, you call the `Enable-D365Exception` cmdlet first and then other cmdlet calls will use the `-EnableException` parameter behind the scenes to throw an exception.\n\n# Why are exceptions handled like this?\n\nThe d365fo.tools PowerShell module is written to help Dynamics 365 Finance and Operations users complete their \"daily\" tasks easier and more efficient, in a structured and repeatable manner. While the main users of the module are people with a technical background, we don't assume that they have pre-existing skills with PowerShell.\n\nThis is why exceptions by default are hidden from the user so that they don't have errors, exceptions and other messages contaminating the console output. In PowerShell community lingo, this is called the \"sea of red\", because errors and exceptions are displayed in a red font. For a new user of PowerShell, this can be a scary thing that makes them look for other solutions.\n\nFor others that are used to having exceptions to handle issues in their programs, this can be tough to get used to. This is why the options described above are provided so that you can switch the d365fo.tools into a mode that increases exposure of any issues.\n\n## Can this be changed?\n\nWe had some discussions in the past on how the module should handle exceptions (take a look at the discussion in issue [#265](https://github.com/d365collaborative/d365fo.tools/issues/265)). While we feel that we are currently in a good place when it comes to exception handling, there is always room for improvements or change. If you want to contribute to that, we encourage you to create an [issue](https://github.com/d365collaborative/d365fo.tools/issues) or [discussion](https://github.com/d365collaborative/d365fo.tools/discussions) or submit a pull request."
  },
  {
    "path": "wiki/Fix-AzureStorageConfig.md",
    "content": "Got hit by our breaking change with the names of the parameters for the Add-AzureStorageConfig, Get-AzureStorageConfig\n\n```\n$configs = Get-D365AzureStorageConfig\n$configs | ForEach-Object {Add-D365AzureStorageConfig -Name $_.Name -AccountId $_.AccountId -SAS $_.SAS -Container $_.Blobname -Force}\n``` "
  },
  {
    "path": "wiki/Getting-Started-with-GitHub.md",
    "content": "If you have never worked with GitHub/Git it can be challenging to know where to begin. The purpose of this page is to just simply provide some good references (bookmarks) that can help you get started more quickly....and easily.\n\n## Understanding the process/tools\n[How to Github: Fork, Branch, Track, Squash and Pull Request](https://gun.io/blog/how-to-github-fork-branch-and-pull-request/)\n\n[Contributing to Projects with GitHub Desktop](https://help.github.com/desktop/guides/contributing/)\n\n## Actually doing it\n[Learning Git Branching](http://learngitbranching.js.org/) - Online lab of sorts for trying out and learning Git command line.\n\n## Creating your first pull request\nIf you feel for fixing a bug, but don't know GitHub enough, the [dbatool.io](https://github.com/sqlcollaborative/dbatools) project has a good starting guide. We are on the same team, so instead of us writing a guide that is close to theirs - we simply point to theirs [step-by-step guide](https://dbatools.io/firstpull).\n\n## Really cool tutorial site!\n[git-scm](https://git-scm.com/)\n\n**Note:** This entire page is deeply inspired by the work done over in the [dbatool.io](https://github.com/sqlcollaborative/dbatools) module. Pay them a visit and learn from the very same people as we did."
  },
  {
    "path": "wiki/Home.md",
    "content": "Welcome to the d365fo.tools wiki!\n\nHere we will write small guides on how to accomplish different tasks by providing a guided example with all the different cmdlets needed to get the job done."
  },
  {
    "path": "wiki/How-To-Authenticate-With-LCS-API.md",
    "content": "﻿# **LCS API Authentication**\n\nThe LCS (Lifecycle Services) API authentication will enable you to use the functionality provided by the LCS API.\n\nThis how-to will guide you on how to authenticate with the LCS API using the d365fo.tools and persist the LCS API details on your machine. This way you don't need to remember the finer details when you start using other cmdlets of the d365fo.tools that make use of the LCS API.\n\n## **Prerequisites**\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n* User account without MFA enabled\n   * Should already be able to log into LCS and be part of the project\n* Registered Application in the Azure AD\n  * Needs to have the \"Dynamics Lifecycle services\" permission assigned and granted/consented\n* LCS Project Id\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) tutorial to see the different ways you can load the d365fo.module into a PowerShell session.\n\nTo learn more about the prerequisites for this how-to, you should visit Adrià Ariste's [blog](https://ariste.info/en) - more specific the following [guide](https://ariste.info/en/msdyn365-azure-devops-alm), [chapter \"Release Pipelines\"](https://ariste.info/en/dynamics365almguide/setting-up-release-pipeline-in-azure-devops-for-dynamics-365-for-finance-and-operations/) & [chapter \"LCS DB API\"](https://ariste.info/en/dynamics365almguide/call-the-lcs-database-movement-api-from-your-azure-devops-pipelines/)\n\n## **Configure LCS API access details**\nFor you to be able to communicate with the LCS API, you will need an username, password and a registered application. As mentioned in the prerequisites, you should read the blog post from Adrià Ariste.\n\nThe following script will:\n1. Test that your username, password and registered application is working\n2. Store the authentication token and registered application along with the LCS project id\n\n```powershell\n# We will start by testing that we can obtain a valid OAuth token, to make sure our details are correct\nGet-D365LcsApiToken -ClientId \"e70cac82-6a7c-4f9e-a8b9-e707b961e986\" -Username \"Lcs-Automation@contoso.com\" -Password \"fT1DHcLdeTWC9aumugHr\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\"\n\n# Now we are going to save the details, the refresh token, the registered application and the project id\nGet-D365LcsApiToken -ClientId \"e70cac82-6a7c-4f9e-a8b9-e707b961e986\" -Username \"Lcs-Automation@contoso.com\" -Password \"fT1DHcLdeTWC9aumugHr\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\" | Set-D365LcsApiConfig -ProjectId \"123456789\" -ClientId \"e70cac82-6a7c-4f9e-a8b9-e707b961e986\"\n```\n\n[[images/howtos/Authenticate-LCS-API.gif]]\n\nSo now you will have the authentication token, the registered application and the project id persisted on your machine, which will enable different cmdlets to utilize them going forward."
  },
  {
    "path": "wiki/How-To-Compile-Model.md",
    "content": "﻿# **Compile module**\n\nThis how-to will guide you on how to compile a module without using Visual Studio.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) tutorial to see the different ways you can load the d365fo.module into a PowerShell session.\n\n## **List all modules / models**\nListing all installed modules / models can help you while troubleshooting your environment. Type the following command:\n\n```PowerShell\nGet-D365Module\n```\n\n[[images/howtos/Get-Modules.gif]]\n\n\n## **Search for modules / models**\nTo limit the output of modules in the console, you can utilize the search functionality in the `Get-D365Module` cmdlet. Type the following command:\n\n```PowerShell\nGet-D365Module -Name *Project*\n```\n\n[[images/howtos/Get-Modules-Search.gif]]\n\n\n## **Compile module / model**\nWe need to know the name of the module / model that we want to compile, and provide that as a parameter. Type the following command:\n\n```PowerShell\nInvoke-D365ModuleFullCompile -Module Project\n```\n\n[[images/howtos/Compile-Single-Module.gif]]\n\n\n## **Compile multiple modules / models**\nWe can utilize the `Get-D365Module` cmdlet and its output to the PowerShell pipeline, to supply the needed parameters to the `Invoke-D365ModuleFullCompile` cmdlet. Type the following command:\n\n```PowerShell\nGet-D365Module -Name *Project* | Invoke-D365ModuleFullCompile\n```\n\n[[images/howtos/Compile-Modules.gif]]\n\nYou can also use utilize `-InDependencyOrder` parameter of `Get-D365Module` to get and compile modules in the right order. One module\nmight depend on other modules and this allows you to compile dependencies first.\n\n## **Closing comments**\nIn this how to we showed you how to compile a specific module / model in a D365FO environment. We also showed you how to combine the `Get-D365Module` cmdlet with the `Invoke-D365ModuleFullCompile` cmdlet to make it easier to compile multiple modules / models."
  },
  {
    "path": "wiki/How-To-Download-Latest-Bacpac-From-Lcs.md",
    "content": "﻿\n# **Download latest bacpac from LCS via AzCopy**\n\nThis how-to will guide you on how to utilize the LCS API and download the latest bacpac file via the AzCopy.exe, and showing you how to increase the download speed with a nice little trick.\n\n- **TOC**\n  * [**Prerequisites**](#--prerequisites--)\n  * [**Configure Azure Storage Account**](#--configure-azure-storage-account--)\n  * [**Configure LCS API access details**](#--configure-lcs-api-access-details--)\n  * [**Download the latest bacpac file from LCS via AzCopy**](#--download-the-lastest-bacpac-file-from-lcs-via-azcopy--)\n  * [**Closing comments**](#--closing-comments--)\n  \n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n* AzCopy installed\n  * https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Install-AzCopy\n* Azure Storage account\n* Blob Container\n* SAS token to Blob Container\n   * To make the initial testing easier, it should be full permission\n* User account without MFA enabled\n   * Should already be able to log into LCS and be part of the project\n* Registered Application in the Azure AD\n  * Needs to have the \"Dynamics Lifecycle services\" permission assigned and granted/consented\n* LCS Project Id\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) tutorial to see the different ways you can load the d365fo.module into a PowerShell session.\n\nTo learn more about the prerequisites for this how-to, you should visit Adrià Ariste's [blog](https://ariste.info/en) - more specific the following [guide](https://ariste.info/en/msdyn365-azure-devops-alm), [chapter \"Release Pipelines\"](https://ariste.info/en/dynamics365almguide/setting-up-release-pipeline-in-azure-devops-for-dynamics-365-for-finance-and-operations/) & [chapter \"LCS DB API\"](https://ariste.info/en/dynamics365almguide/call-the-lcs-database-movement-api-from-your-azure-devops-pipelines/)\n\n## **Configure Azure Storage Account**\nTo make things easier going forward, we will register your Azure Storage Account details and persist them on your machine. This way you don't need to remember the finer details, but can still utilize the increased transfer speed.\n\nThe following script will:\n1. Add the connection details and store them\n2. Show the newly added details\n3. Configure the added details as the active configuration\n   1. This will be persisted for the next time you load the module\n4. List all files/blobs that are already inside your container\n   \n```powershell\n#We'll start with adding and storing the connection details for the Azure Storage Account\nAdd-D365AzureStorageConfig -Name \"TestAccount\" -AccountId \"motz\" -Container \"demo\" -SAS \"?sv=2018-03-28&si=full&sr=c&sig=N3vCp95UUhlpdBxL5QZCjOrp0o30Yxdj17PJ70nxMc4%3D\"\n\n#Let's see the details we just saved\nGet-D365AzureStorageConfig\n\n#Now we are going to set the config as the active\nSet-D365ActiveAzureStorageConfig -Name \"TestAccount\"\n\n#Do we have anything in it already?\nGet-D365AzureStorageFile\n```\n\n[[images/howtos/01.00-LCS-API-Add-D365AzureStorageConfig.gif]]\n\nSo now you will have an Azure Storage Account and its configuration details persisted on your machine, which will enable different cmdlets to utilize it going forward.\n\n## **Authenticate with LCS and retrieve database backup information from LCS**\nThe following cmdlets show how you can retrieve information about database backups that exist in LCS. We will later use this information to retrieve the backups.\n\nTo call these and other cmdlets, you need to authenticate the d365fo.tools with LCS. A how-to for the authentication can be found at [Authenticate with LCS API](How-To-Authenticate-With-LCS-API). \n\nThe following script will:\n1. Authenticate with the LCS API and store the refresh token and registered application along with the LCS project id\n2. List all available bacpacs and backups from the LCS Asset Library\n3. List the latest bacpac / backup from the LCS Asset Library\n\n```powershell\n# Authenticate with the LCS API and save the details, the refresh token, the registered application and the project id\nGet-D365LcsApiToken -ClientId \"e70cac82-6a7c-4f9e-a8b9-e707b961e986\" -Username \"Lcs-Automation@contoso.com\" -Password \"fT1DHcLdeTWC9aumugHr\" -LcsApiUri \"https://lcsapi.lcs.dynamics.com\" | Set-D365LcsApiConfig -ProjectId \"123456789\" -ClientId \"e70cac82-6a7c-4f9e-a8b9-e707b961e986\"\n\n# Retrieve a list of available backups\nGet-D365LcsDatabaseBackups\n\n# Retrieve only the latest backup\nGet-D365LcsDatabaseBackups -Latest\n```\n\n[[images/howtos/Authenticate-LCS-Get-Backups.gif]]\n\nSo now you are authenticated with LCS and have information about the database backups that can be transferred. This enables the utilization of other cmdlets going forward.\n\n## **Download the latest bacpac file from LCS via AzCopy**\nAzCopy is capable of working with different Azure Storage components / services, and the backend of the LCS Asset Library is in fact an Azure Storage Account, with some containers. One of the major capabilities of AzCopy, is that it can facilitate a transfer between 2 isolated Azure Storage Accounts, as long as you provide a complete Url/Uri, including a SAS token.\n\nWhenever you list backups from the LCS API, the output will always contain a complete url for the specific file, containing a SAS token.\n\nBecause you have saved the configuration details for our own Azure Storage Account, we are also capable of generating a complete Url/Uri, containing a SAS token.\n\nYou need to concatenate the full URL/URI for you own Azure Storage Account, the container name, the desired destination filename and the SAS token that you must have in place for the container.\n\nThe following script will:\n1. Generate a complete Url/Uri, containing a SAS token\n2. Start the transfer of the latest bacpac file and into our own\n3. List all available bacpacs and backups from the LCS Asset Library\n4. List the latest bacpac / backup from the LCS Asset Library\n\n```powershell\n# With the Azure Storage Account persisted, we can now generate a complete Url/Uri\nGet-D365AzureStorageUrl\n\n# Let us connect the dots and utilize the Azure Storage Account to speed up the download\n# Generate complete Url/Uri\n$TempDestination = Get-D365AzureStorageUrl -OutputAsHashtable\n\n# Transfer the latest bacpac file from LCS to our own Azure Storage Account\n$BlobParms = Get-D365LcsDatabaseBackups -Latest | Invoke-D365AzCopyTransfer @TempDestination -FileName \"Latest.bacpac\"\n\n# Let us see if we really got the bacpac file transferred into our own Azure Storage Account\nGet-D365AzureStorageFile\n\n# Transfer the bacpac file from our Azure Storage Account and onto our machine.\n$BlobParms | Invoke-D365AzCopyTransfer -DestinationUri \"C:\\Temp\" -DeleteOnTransferComplete\n\n# Let us see if we removed the temporary file from our Azure Storage Account\nGet-D365AzureStorageFile\n```\n\n[[images/howtos/01.02-LCS-API-Get-D365LcsDatabaseBackups.gif]]\n\nSo now you will have the latest bacpac file downloaded onto your own machine, while removing the temporary file from the Azure Storage Account.\n\n## **Closing comments**\nIn this how to we showed you how to utilize the AzCopy.exe as a tool to speed up the download process of files stored in the LCS Storage Account. You learned how to persist the Azure Storage Account details, along with the refresh token, register application and the LCS project id."
  },
  {
    "path": "wiki/How-To-Enable-Users-In-Db.md",
    "content": "﻿# **Enable users in the D365FO environment**\n\nThis how-to will guide you on how to enable users in the database. This is required if you import a bacpac file that comes directly from a D365FO production instance, or if someone has disabled the users for others reasons.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) tutorial to see the different ways you can load the d365fo.module into a PowerShell session.\n\n## **Enabling the users in the database**\nWe want to enable all NON-SYSTEM user accounts in the D365FO database, and that way allow them to logon to the D365FO environment. Type the following command:\n\n```\nGet-D365User -ExcludeSystemUsers | Enable-D365User\n```\n\n[[images/howtos/Enable-Users.gif]]\n\n## **Closing comments**\nIn this how to we showed you how to enable all NON-SYSTEM user accounts in the D365FO database. After this operation all users are now enabled and capable of logging into the D365FO environment."
  },
  {
    "path": "wiki/How-To-Export-Bacpac-From-Tier1.md",
    "content": "﻿# **Export a bacpac file from a Tier1 environment**\n\nThis how-to will guide you while you will be exporting a bacpac file from a Tier1 environment.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) tutorial to see the different ways you can load the d365fo.module into a PowerShell session.\n\n## **Stop all D365FO services**\nWe need to stop all D365FO related services, to ensure that our database isn't being updated while we are exporting it. Type the following command:\n\n```\nStop-D365Environment -All\n```\n\n[[images/howtos/Stop-Services.gif]]\n\n## **Export bacpac file**\nWe will now export the bacpac file, and instruct the command to output the progress, so we can see that things are running as expected. Type the following command:\n\n```\nNew-D365Bacpac -ExportModeTier1 -ShowOriginalProgress\n```\n\n[[images/howtos/Export-Bacpac.gif]]\n\nThe command will run for quite some time, but it will eventually exit and output the file location of the newly created bacpac file.\n\n## **Closing comments**\nIn this how to we showed you how you can create a valid bacpac file from a Tier1 environment. The bacpac file is prepped for either other Tier1 environments, but is also valid for Tier2+ environments, through the LCS portal.\n"
  },
  {
    "path": "wiki/How-To-Import-Bacpac-Into-Tier1.md",
    "content": "﻿# **Import a bacpac file into a Tier1 environment**\n\nThis how-to will guide you while you will be importing a bacpac file into a Tier1 environment.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n* Valid bacpac file\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) tutorial to see the different ways you can load the d365fo.module into a PowerShell session.\n\n## **Import bacpac file into the SQL Server**\nWe want to import the bacpac file into the SQL Server, and we want to do that into a new database. Type the following command:\n\n```\nImport-D365Bacpac -BacpacFile \"C:\\Temp\\d365fo.tools\\AxDB.bacpac\" -ImportModeTier1 -NewDatabaseName GOLDEN\n```\n\n[[images/howtos/Import-Bacpac.gif]]\n\n### Troubleshooting\n\nIf you get an error message during this step that complains about a missing `sqlpackage.exe`, run the following command before running the `Import-D365Bacpac` command again.\n\n```\nInvoke-D365InstallSqlPackage\n```\n\n## **Stop all D365FO services**\nWe need to stop all D365FO related services, to ensure that our D365FO database isn't being lock when we are going to update it. Type the following command:\n\n```\nStop-D365Environment -All\n```\n\n[[images/howtos/Stop-Services.gif]]\n\n## **Switch databases**\nWith the newly created GOLDEN database, we will be switching it in as the D365FO database. Type the following command:\n\n```\nSwitch-D365ActiveDatabase -SourceDatabaseName GOLDEN\n```\n\n[[images/howtos/Switch-Database.gif]]\n\n## **Synchronize the D365FO databases**\nWith the newly GOLDEN database switched in a the D365FO database, we need to ensure that the codebase and the database is synchronized correctly and fully working. Type the following command:\n\n```\nInvoke-D365DBSync -ShowOriginalProgress\n```\n\n[[images/howtos/Invoke-DBSync.gif]]\n\n## **Start all D365FO services**\nWith the synchronization of the database completed, we need to start all D365FO related services again, to make the D365FO environment available again. Type the following command:\n\n```\nStart-D365Environment -All\n```\n\n[[/images/howtos/Start-Services.gif]]\n\n## **Closing comments**\nIn this how to we showed you how you can update a Tier1 environment with a bacpac file, and how to make sure that the database is synchronized with the codebase. Depending on where you obtained the bacpac file from, you might need to [update](How-To-Update-Users-In-Db) and/or [enable](How-To-Enable-Users-In-Db) the users. Please refer to the How To section and learn how to complete either task.\n"
  },
  {
    "path": "wiki/How-To-Import-External-User-Into-Db.md",
    "content": "﻿# **Import external users into the D365FO environment**\n\nThis how-to will guide you on how to import external users into your D365 environment.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) tutorial to see the different ways you can load the d365fo.module into a PowerShell session.\n\n## **Import an external user into the database**\nWe are going to import a single user account into the D365FO database. The sign-in name / e-mail has to be the primary sign-in name of the account. Type the following command:\n\n**Note:** You will need to fill in the id and the name which the account should have in the database, because we can't look that up with this command.\n\n```\nImport-D365ExternalUser -Id test -Name test -Email test@e-s.dk\n```\n\n[[images/howtos/Import-ExternalUser.gif]]\n\n## **Closing comments**\nIn this how to we showed you how to import an external user into the D365FO database."
  },
  {
    "path": "wiki/How-To-Import-User-Into-Db.md",
    "content": "﻿# **Import users into the D365FO environment**\n\nThis how-to will guide you on how to import users into your D365 environment.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n* Valid Azure AD user account capable of signing into Office365\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) tutorial to see the different ways you can load the d365fo.module into a PowerShell session.\n\n## **Import an user into the database**\nWe are going to import a single user account into the D365FO database. The user has to be licensed with an valid Office365 mailbox. The sign-in name / e-mail has to be the primary sign-in name of the account. Type the following command:\n\n**Note:** You need an account capable of signing into Office365, which will resolve the user account that you importing. The account that you're importing **can** be the same as the account you're signing in with.\n\n```\nImport-D365AadUser -Users test@e-s.dk\n```\n\n[[images/howtos/Import-AadUser.gif]]\n\n## **Closing comments**\nIn this how to we showed you how to import an Azure AD user into the D365FO database."
  },
  {
    "path": "wiki/How-To-Install-AzCopy.md",
    "content": "﻿# **Install AzCopy**\n\nThis how-to will guide you on how to install the latest available AzCopy onto your machine.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) tutorial to see the different ways you can load the d365fo.module into a PowerShell session.\n\n## **Install latest AzCopy**\nInstallation of the latest AzCopy is done with the `Invoke-D365InstallAzCopy` cmdlet. Using this command will also update the internal path inside the module pointing to the AzCopy.exe. Type the following command:\n\n```\nInvoke-D365InstallAzCopy\n```\n\n[[images/howtos/Invoke-InstallAzCopy.gif]]\n\n## **Closing comments**\nIn this how to we showed you how to install the latest AzCopy on your machine. By using the `Invoke-D365InstallAzCopy` cmdlet, you also updated the path for the module where to look for AzCopy.exe. If you just want to update the path for the AzCopy.exe, you can look into the `Set-D365AzCopyPath` cmdlet."
  },
  {
    "path": "wiki/How-To-Install-NuGet.md",
    "content": "﻿# **Install NuGet**\n\nThis how-to will guide you on how to install the latest available nuget.exe onto your machine.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) tutorial to see the different ways you can load the d365fo.module into a PowerShell session.\n\n## **Install latest nuget.exe**\nInstallation of the latest NuGet is done with the `Invoke-D365InstallNuget` cmdlet. Using this command will also update the internal path inside the module pointing to the nuget.exe. Type the following command:\n\n```\nInvoke-D365InstallNuget\n```\n\n[[images/howtos/Invoke-D365InstallNuget.gif]]\n\n## **Closing comments**\nIn this how to we showed you how to install the latest NuGet on your machine. By using the `Invoke-D365InstallNuget` cmdlet, you also updated the path for the module where to look for nuget.exe. If you just want to update the path for the nuget.exe, you can look into the `Set-D365NugetPath` cmdlet."
  },
  {
    "path": "wiki/How-To-Install-SqlPackage.md",
    "content": "﻿# **Install SqlPackage**\n\nThis how-to will guide you on how to install the latest available SqlPackage onto your machine.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) tutorial to see the different ways you can load the d365fo.module into a PowerShell session.\n\n## **Install latest SqlPackage**\nInstallation of the latest AzCopy is done with the `Invoke-D365InstallSqlPackage` cmdlet. Using this command will also update the internal path inside the module pointing to the SqlPackage.exe. Type the following command:\n\n```\nInvoke-D365InstallSqlPackage\n```\n\n[[images/howtos/Invoke-InstallSqlPackage.gif]]\n\n## **Closing comments**\nIn this how to we showed you how to install the latest SqlPackage.exe on your machine. By using the `Invoke-D365InstallSqlPackage` cmdlet, you also updated the path for the module where to look for SqlPackage.exe. If you just want to update the path for the SqlPackage.exe, you can look into the `Set-D365SqlPackagePath` cmdlet."
  },
  {
    "path": "wiki/How-To-List-Models.md",
    "content": "﻿# **List modules / models**\n\nThis how-to will guide you on how to list and search for modules / models.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) tutorial to see the different ways you can load the d365fo.module into a PowerShell session.\n\n## **List all modules / models**\nListing all installed modules / models can help you while troubleshooting your environment. Type the following command:\n\n```PowerShell\nGet-D365Module\n```\n\n[[images/howtos/Get-Modules.gif]]\n\n\n## **List all modules / models**\nTo limit the output of modules in the console, you can utilize the search functionality in the `Get-D365Module` cmdlet. Type the following command:\n\n```PowerShell\nGet-D365Module -Name *Project*\n```\n\n[[images/howtos/Get-Modules-Search.gif]]\n\n## **Closing comments**\nIn this how to we showed you how to list all modules / models in a D365FO environment. We also showed how the cmdlet also supports searching capabilities, to limit the output of modules / models."
  },
  {
    "path": "wiki/How-To-Provision-Environment-Tier1.md",
    "content": "﻿# **Provision D365FO environment to new Azure AD tenant**\n\nThis how-to will guide you on how to provision Tier1 environment to be connected to new Azure AD tenant.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n* Valid Azure AD user account that should be assigned as the D365FO administrator\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) tutorial to see the different ways you can load the d365fo.module into a PowerShell session.\n\n## **Provision user to the new D365FO administrator in the database**\nFor us to provision the Tier1 environment to be connected to a new Azure AD tenant, we need to change the administrator of the D365FO instance. Type the following command:\n\nPlease note that the value for the AdminSignInName parameter should be a user account using it **primary** domain. Replace \"test@e-s.dk\" with the user account you want to use.\n\n```\nSet-D365Admin -AdminSignInName test@e-s.dk\n```\n\n[[images/howtos/Provision-Admin.gif]]\n\n### **Troubleshooting**\nYou might face an error while trying to provision the new administrator. This issue is connected to the Batch service running. We have seen several issues where we are unable to stop the service with the normal tools available, even standard Windows tools. We have seen 2 ways to fix this issue: First option is a simple restart of the entire machine and straight after the reboot try doing it again. Second option is to kill the Batch service using the Task Manager.\n\n## **Closing comments**\nIn this how to we showed you how to can provision the D365FO environment to a new Azure AD tenant, by switching out the D365FO administrator.\n\nIf the environment has external users imported already, you will need to follow the **How-To-Update-Users** how to before they can access the environment."
  },
  {
    "path": "wiki/How-To-Register-NuGet-Source.md",
    "content": "﻿# **Register NuGet source**\n\nThis how-to will guide you on how to registered a NuGet source to be used with some of the cmdlets from the #d365fo.tools module.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n* NuGet installed (via Invoke-D365InstallNuget)\n* Valid Personal Access Token (PAT) obtained from the Azure DevOps project your Azure DevOps feed is hosted\n* Correctly formatted feed url for the Azure DevOps feed your want to work against\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [How To Install NuGet](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Install-NuGet) tutorial to see how the d365fo.module can install the latest version of NuGet.\n\nPlease visit the [Use personal access tokens](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=preview-page) official guide to see how to create a PAT in Azure DevOps. Please note you need only Packaging (Read, Write & Manage).\n\nA correctly formatted feed url is like:\nhttps://pkgs.dev.azure.com/OrganizationName/ProjectName/_packaging/FeedName/NuGet/v3/index.json\n\nWhere you need to fill in the **OrganizationName** - **ProjectName** - **FeedName** details. E.g.\nhttps://pkgs.dev.azure.com/Contoso/DynamicsFnO/_packaging/D365Packages/nuget/v3/index.json\n\n## **Register NuGet source**\nEither locate the local install location of NuGet, or registered it in your environment path variables. If installed via the Invoke-D365InstallNuGet it will default be located **\"C:\\Temp\\d365fo.tools\\NuGet\"**. Type the following command:\n\n```powershell\ncd \"C:\\Temp\\d365fo.tools\\NuGet\"\n```\n\nNow you need the PAT from your Azure DevOps Project. This will be stored on the local machine, so please be advised that you shouldn't do this on machines that you don't trust. Type the following command:\n\n```powershell\n.\\nuget sources add -Name \"D365FO\" -Source \"https://pkgs.dev.azure.com/Contoso/DynamicsFnO/_packaging/D365Packages/NuGet/v3/index.json\" -username \"alice@contoso.dk\" -password \"uVWw43FLzaWk9H2EDguXMVYD3DaWj3aHBL6bfZkc21cmkwoK8X78\"\n```\n\n## **Closing comments**\nIn this how to we showed you how to register a local NuGet source on your machine. This enables you to have different sources registered on the same machine, so updating multiple customer projects should be made simpler. The name used for the source is to be used with `Invoke-D365AzureDevOpsNuGetPush` when it needs to push new packages to the Azure DevOps feed."
  },
  {
    "path": "wiki/How-To-Start-Stop-List-D365FO-Services.md",
    "content": "﻿# **Start, Stop and List services**\n\nThis how to will guide you on how to manage the different D365FO services on a machine.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) tutorial to see the different ways you can load the d365fo.module into a PowerShell session.\n\n## **List all available D365FO services**\nIf you want to see the entire list of D365FO services and/or see their current running state, type the following command:\n\n```\nGet-D365Environment -All\n```\n\n### **Output while services are running**\n\n[[images/howtos/Get-Services-While-Running.gif]]\n\n### **Output while services are stopped**\n\n[[images/howtos/Get-Services-While-Stopped.gif]]\n\n## **Stop all D365FO services**\nIf you want to stop all services on the machine, maybe you want to install an update or import a model, type the following command:\n\n```\nStop-D365Environment -All\n```\n\n[[images/howtos/Stop-Services.gif]]\n\n## **Start all D365FO services**\nIf you want to start all services on the machine, type the following command:\n\n```\nStart-D365Environment -All\n```\n\n[[images/howtos/Start-Services.gif]]\n\n## **Restart all D365FO services**\nIf you want to restart all services on the machine, maybe because you are having some issues with caching, type the following command:\n\n```\nRestart-D365Environment -All\n```\n\n[[images/howtos/Restart-Services.gif]]\n\n## **Closing comments**\nIn this how to we showed you how to use the d365fo.tools module to manage the different D365FO specific services."
  },
  {
    "path": "wiki/How-To-Transfer-Via-AzCopy.md",
    "content": "﻿# **Speed up LCS download via AzCopy**\n\nThis how-to will guide you on how to utilize the AzCopy.exe tool to increase the download speed from the LCS asset library. It can be the Shared Asset Library or it can be a Project specific Asset Library.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n* Storage account (Full url is needed)\n* Blob Container\n* SAS token to Blob Container, should be a full permission while testing\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) tutorial to see the different ways you can load the d365fo.module into a PowerShell session.\n\n## **Start download from LCS via the browser**\nWe need to get a hold of a complete source url from LCS, and thankfully it is super easy. Please see below guide:\n\n[[images/howtos/LCS-Download-v2.gif]]\n\nThe end result is that you have a full URL/URI for the file that you want to transfer. The URL/URI will contain a valid SAS token, but will be time limited.\n\nThe source URL/URI in our example is:\n\"https://uswedpl1catalog.blob.core.windows.net/product-ax7productname/476c13c6-7e3d-49c4-a377-f1282fd7ad16/AX7ProductName-12-24-92935151-8f5b-45d6-9aea-392bd74bd6ec-476c13c6-7e3d-49c4-a377-f1282fd7ad16?sv=2015-12-11&sr=b&sig=ChCHvZD3eFtcHYU1n%2FqXDmKzUTbcXNefMwbVKyRKyiU%3D&se=2019-11-23T14%3A28%3A15Z&sp=r\"\n\n## **Transfer the file into your own Storage Account**\nYou need to concatenate the full URL/URI for you own Azure Storage Account, the container name, the desired destination filename and the SAS token that you must have in place for the container.\n\nIn out example these are the following details:\n\n**Storage Account URL/URI**: \"https://motz.blob.core.windows.net/\"\n\n**Container Name**: \"azcopytest\"\n\n**SAS Token**: \"?sv=2018-03-28&si=full&sr=c&sig=PH5douKkqJJrbl8CoQjizopFCtgnL50aLUJzY0k1Xqc%3D\"\n\n**Desired Filename**: \"FinandOps10.0.5.part16.rar\"\n\nThe combined destination URL/URI ends up being:\n\"https://motz.blob.core.windows.net/azcopytest/FinandOps10.0.5.part16.rar?sv=2018-03-28&si=full&sr=c&sig=PH5douKkqJJrbl8CoQjizopFCtgnL50aLUJzY0k1Xqc%3D\"\n\nWith both the source and destination URL's/URI's at hand, we can start the transfer between the LCS Storage Account and our own Storage Account. Type the following command:\n\n```\nInvoke-D365AzCopyTransfer -SourceUri \"https://uswedpl1catalog.blob.core.windows.net/product-ax7productname/476c13c6-7e3d-49c4-a377-f1282fd7ad16/AX7ProductName-12-24-92935151-8f5b-45d6-9aea-392bd74bd6ec-476c13c6-7e3d-49c4-a377-f1282fd7ad16?sv=2015-12-11&sr=b&sig=ChCHvZD3eFtcHYU1n%2FqXDmKzUTbcXNefMwbVKyRKyiU%3D&se=2019-11-23T14%3A28%3A15Z&sp=r\" -DestinationUri \"https://motz.blob.core.windows.net/azcopytest/FinandOps10.0.5.part16.rar?sv=2018-03-28&si=full&sr=c&sig=PH5douKkqJJrbl8CoQjizopFCtgnL50aLUJzY0k1Xqc%3D\" -ShowOriginalProgress\n```\n\n[[images/howtos/Transfer-From-Lcs-To-Own-Storage.gif]]\n\nHere you can see that the file is actually stored in the container under our Storage Account.\n\n[[images/howtos/Show-File-In-Blob-Container.gif]]\n\n## **Transfer the file from your own Storage Account to your machine**\nWhen the transfer into your own Storage Account, you can use the same URL/URI as the new source URL/URI, and then fill in a local folder path to where you want the file to be saved. Type the following command:\n\n```\nInvoke-D365AzCopyTransfer -SourceUri \"https://motz.blob.core.windows.net/azcopytest/FinandOps10.0.5.part16.rar?sv=2018-03-28&si=full&sr=c&sig=PH5douKkqJJrbl8CoQjizopFCtgnL50aLUJzY0k1Xqc%3D\" -DestinationUri \"c:\\temp\\d365fo.tools\\FinandOps10.0.5.part16.rar\" -ShowOriginalProgress\n```\n\n[[images/howtos/Transfer-From-Own-Storage-To-Local.gif]]\n\nHere you can see that the file is actually stored our machine.\n\n[[images/howtos/Show-File-Local.png]]\n\n## **Closing comments**\nIn this how to we showed you how to utilize the AzCopy.exe as a tool to speed up the download process of files stored in the LCS Storage Account. It might seem a bit technical at first, but when you first learn that you are only working with a source and a destination URL/URI, it should be a doable task going foward. The `Invoke-D365AzCopyTransfer` cmdlet has a `-Filename` parameter that can help you to ease the work of concatenation, because you can then reuse the same destination URL/URI and only change the filename between multiple file transfers."
  },
  {
    "path": "wiki/How-To-Update-Users-In-Db.md",
    "content": "﻿# **Update users in the D365FO environment**\n\nThis how-to will guide you on how to update all NON-SYSTEM users in the database. This is required if you provision your D365FO environment to be connected to a new Azure AD tenant.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n* d365fo.tools module loaded into a PowerShell session\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\nPlease visit the [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) tutorial to see the different ways you can load the d365fo.module into a PowerShell session.\n\n## **Update the users in the database**\nWe want to update all NON-SYSTEM user accounts in the D365FO database, and that way allow them to logon to the D365FO environment. Type the following command:\n\n```\nGet-D365User -ExcludeSystemUsers | Update-D365User\n```\n\n[[images/howtos/Update-Users.gif]]\n\n## **Closing comments**\nIn this how to we showed you how to update all NON-SYSTEM user accounts in the D365FO database. After this operation all users are now updated with their provider matching the Azure AD tenant of the D365FO environment."
  },
  {
    "path": "wiki/How-To-Write-Wiki-Pages.md",
    "content": "# Create gifs\n\nTo create gif files from a PowerShell cmdlet execution, you can use the following two programs to\n- record the execution: [ShareX](https://getsharex.com/)\n- fine tune the gif: [ScreenToGif](https://www.screentogif.com/)\n\nAfter the initial gif has been recorded with ShareX, you can use ScreenToGif to strip out all the 100% identical images in the gif, add a custom wait time across all the images and duplicate the last image and set the wait for 1-3 seconds.\n\nYou can open one of the existing gifs in ScreenToGif to see what wait timeout is configured."
  },
  {
    "path": "wiki/Implementing-the-messaging-system.md",
    "content": "The messaging system in d365fo.tools is a powerful tool to centralize all informational data and manage its flow. Simply put: You give it a message you want to write, and tell the system how important it is (what Level it has) and the system will handle 'the rest'.\nThe rest being ...\n- Logging the message\n- Deciding whether it should be written to the console screen (host/information)\n- Deciding whether it should be written to verbose only\n- Deciding whether it should be written to debug\n- Deciding whether it should be written as a warning\nIt will also automatically add a timestamp and the name of the function calling it to the message.\n\nHere's a simple example on how to use it:\n```PowerShell\nWrite-PSFMessage -Level Verbose -Message \"I'm an example message and will probably - but not necessarily - written to the verbose stream\"\n```\n\n# The Levels of power\nThere are 10 Levels you can choose from when writing a message. d365fo.tools-users can configure 9 of them as they please, controlling how much verbosity they want. Only the warning level cannot be altered by the user.\n\nBy default, the first three levels are written to screen:\n* Critical / 1\n* Important / Output / 2\n* Significant / 3\n\nBy default, the second set of three levels are written to verbose only:\n* VeryVerbose / 4\n* Verbose / 5\n* SomewhatVerbose / 6\n\nAll messages get sent to debug by default, but three more levels exist that are debug only:\n* System / 7\n* Debug / 8\n* InternalComment / 9\n\nFinally, there's the warning level:\n* Warning / 666\n\nIn all cases, both the text as well as the numerical value can be used at your own discretion.\n\n# When to use?\n\nBasically, Write-Message _completely replaces_ all instances of Write-Host, Write-Information, Write-Verbose, Write-Debug, Write-Warning and Write-Output. If you'd use one of those, use Write-Message instead. (Write-Output has seen lots of misuse for verbose communication with the user, and has thus been deprecated for use of generating actual output objects.)\nAs a general guideline though:\n\n## When to give warning\n\nWhenever something fails but isn't bad enough to warrant terminating the function (or skipping to the next input) over, it's time to use Write-Message's warning level:\n\n```PowerShell\nWrite-Message -Level Warning -Message \"Failed to access XYZ. Continuing but will lack some information\"\n```\nAs shown in the example, this is usually used when a function fails to access supplementary data.\n\nThis is *not* intended for use when something crippling happens, something you'd stop the function or skip processing the current input item over! See the guide on flow control and `Stop-Function` for details on how to handle that.\n\n## When to directly contact the user\n\nThe first three Levels are reserved for things that the human user must be communicated with. Which Level to use is at the discretion of the developer - in case of doubt use Important/Output/2 - the greater the impact of whatever is being communicated, the lower (numeric based) the Level should be.\n\nThings that should be communicated to the user:\n- Deprecation warnings\n- Loading additional resources that one would not expect to need when running the function (e.g.: Importing another module)\n- Sanity checks. Keeping users from committing folly is high on our todo list.\n- Information that may induce a human user to interrupt execution\n\n## This ain't no chat engine\n\nThe verbose Levels - VeryVerbose/4, Verbose/5 and SomewhatVerbose/6 - exist to provide general status information, what the function is doing right now. This means it is not shown to the user by default, but may be helpful in showing what the function is doing and how fast it is progressing.\n\nGeneral usage and associated Level:\n- Setup actions taken in the begin block: Verbose/5\n- Starting to process an input item (Such as an object received from pipeline): VeryVerbose/4\n- Individual processing phases: Verbose/5\n- Actions that are part of a processing phase: SomewhatVerbose/6\n\nExample:\n\n_Warning: This is only to show the use of the various verbosity levels. It is not meant as an example of good function names and blithely ignores any error handling, in order to not clutter this example!_\n```PowerShell\nfunction Get-Test\n{\n    [CmdletBinding()]\n    Param (\n        [Parameter(ValueFromPipeline = $true)]\n        $InputObject\n    )\n    Begin\n    {\n        Write-Message -Level Verbose -Message \"Connecting to Server\"\n        $smo = Connect-SqlServer\n    }\n    Process\n    {\n        foreach ($Item in $InputObject)\n        {\n            Write-Message -Level VeryVerbose -Message \"Processing $Item\"\n            \n            #region 1) Do Stuff\n            Write-Message -Level Verbose -Message \"Doing stuff with $Item\"\n            Do-Stuff $Item\n            #endregion 1) Do Stuff\n            \n            #region 2) Do more stuff\n            Write-Message -Level Verbose -Message \"Doing more stuff with $Item\"\n            \n            Write-Message -Level SomewhatVerbose -Message \"Converting stuff\"\n            Convert-Stuff $item\n            \n            Write-Message -Level SomewhatVerbose -Message \"Waiting for stuff\"\n            Wait-ForStuff $item\n            \n            Write-Message -Level SomewhatVerbose -Message \"Removing stuff\"\n            Remove-Stuff $item\n            #endregion 2) Do more stuff\n            \n            #region 3) Finish doing stuff\n            Write-Message -Level Verbose -Message \"Finishing doing stuff with $Item\"\n            Close-Stuff $item\n            #endregion 3) Finish doing stuff\n        }\n    }\n    End\n    {\n        Write-Message -Level Verbose -Message \"Disconnecting from Server\"\n        $smo.Disconnect()\n    }\n}\n```\n\n## Debugging messages\n\nFinally, the lower Levels are for debugging purposes only. Feel free to add them wherever it may be convenient to have some information written for debugging purposes but no pretext for even verbose output. Truly, this only exists for log purposes.\nAlso information that is directly development-related (such as immediate SQL statements that will be sent to the SQL server) and of no immediate interest to a user should be written to debug channels only. In that case, it is appropriate to write _two_ messages. One (on the verbose side) for the action being taken in humanly understandable text and one (on the debug side, e.g. _System_ or _Debug_) for the actual technical step taken.\n\n# Minimum usage\n\nThe minimum required in a d365fo.tools function is:\n- Warnings as described in the warnings section\n- VeryVerbose and Verbose messages, as shown in the section on verbosity\n\n**Note:** This entire page is deeply inspired by the work done over in the [dbatool.io](https://github.com/sqlcollaborative/dbatools) module. Pay them a visit and learn from the very same people as we did."
  },
  {
    "path": "wiki/Load-individual-files-or-dot-source-the-files.md",
    "content": "When we release a new version of the module all functions are compiled into one big **commands.ps1** file. This is because we want the module to load as fast as possible.\n\nIt has some drawbacks in relation to troubleshooting and tinkering with the module after you have installed it from www.powershellgallery.com\n\nIf you need to change any on the functions on the machine where you installed the module, you can adjust the loading logic, before loading the module and have it load every single function from its source file instead of the compiled commands.ps1.\n\n### **Note**\n**Exit** you current powershell console and start a entirely fresh powershell console, **without** loading the module.\n\n```\nSet-PSFConfig d365fo.tools.Import.IndividualFiles -Value $true\nSet-PSFConfig d365fo.tools.Import.DoDotSource -Value $true \nImport-Module d365fo.tools -Force -Passthru\n```"
  },
  {
    "path": "wiki/Old-readme-examples.md",
    "content": "﻿## **Provided as-is**\nThis page is a direct copy & paste of the old repository readme page. We have stored all the examples here as a courtesy. \n\nSome of the examples are out-dated, while others are still valid and might not made it into the comment based help for the cmdlet / function itself.\n\nIf you find any example here that you believe should be part of the comment based help, please create an issue and tell us. Or even better, create a Pull Request with the example against the repository.\n\n### **Install without administrator privileges**\n```\nInstall-Module -Name d365fo.tools -Scope CurrentUser\n```\n### **List all available commands / functions**\n\n```\nGet-Command -Module d365fo.tools\n```\n\n### **Update the module**\n\n```\nUpdate-Module -name d365fo.tools\n```\n\n### **Get product build numbers**\n\n```\nGet-D365ProductInformation\n```\n\n*Will list all build numbers available, application and platform*\n\n### **Rename a local VM (onebox) to be accessible on a custom URL / URI.**\n\n```\nGet-D365InstanceName\n```\n*Displays the current instance registered on the machine. Run on a machine with the D365 AOS installed on to get an result*\n\n```\nRename-D365Instance -NewName 'Demo1'\n```\n\n*Now the machine (iis) will only respond to request for https://demo1.cloud.onebox.dynamics.com*\n\n### **Change the start page of the browser to another URL / URI**\n\n```\nSet-D365StartPage -Name 'Demo1'\n```\n\n*Now when starting the browser you will start visit https://demo1.cloud.onebox.dynamics.com*\n\n## **Working with users**\n### **Provision a new admin for a given instance**\n\n```\nSet-D365Admin \"admin@contoso.com\"\n```\n\n*Please remember that the username / e-mail has to be a valid Azure Active Directory*\n\n### **Import a list of users into the environment**\n\n```\nImport-D365AadUser -Users \"Claire@contoso.com\",\"Allen@contoso.com\"\n```\n\n*Imports Claire and Allen into the environment*\n\n\n### **Import a list of users into the environment based on Azure AD Group**\n\n```\nImport-D365AadUser -AadGroupName \"D365 Users\" -ForceExactAadGroupName\n```\n\n*Imports all users included into \"D365 Users\" Azure AD Group into the environnement*\n\n*The ForceExactAadGroupName parameter force command to find the AD group by searching for the exact name*\n\n### **Update users in an environment after database migration / restore or re-provisioning**\n\n```\nUpdate-D365User -Email \"claire@contoso.com\"\n```\n*This will search for the user in the UserInfo table with \"claire@contoso.com\" e-mail address and update it with the needed details to get access to the environment*\n\n### **Update users in an environment after database migration / restore or re-provisioning - advanced**\n\n```\nUpdate-D365User -Email \"*contoso.com\"\n```\n\n*This will search for all users in the UserInfo table with the \"contoso.com\" text in their e-mail address and update them with the needed details to get access to the environment*\n\n### **Enable users in an environment after database refresh from Prod to Sandbox**\n\n```\nEnable-D365User -Email \"claire@contoso.com\" \n```\n\n*This will search for the user in the UserInfo table with \"claire@contoso.com\" e-mail address and set enable = 1 if they are not allready enabled, -verbose will show which users where updated*\n\n### **Enable users in an environment after database refresh from Prod to Sandbox - advanced**\n\n```\nEnable-D365User -Email \"*@contoso.com\" \n```\n\n*This will search for the user in the UserInfo table with the \"@contoso.com\" text in their e-mail address and set enable = 1 if they are not allready enabled, -verbose will show which users where updated*\n\n### **Import an user as sysadmin**\n```\nSet-D365SysAdmin\n```\n*This will import the local administrator on the machine into the registered SQL Server.*\n\n**Notes:*You will have to run from an elevated console if you want to avoid supplying username and password***\n\n### **Delete an user**\n```\nRemove-D365User -Email \"Claire@contoso.com\"\n```\n*This will remove the user with the email address \"Claire@contoso.com\" and all the configured security roles.*\n\n## **Work with bacpac files**\n\n### **Generate a bacpac file from a Tier1 environment to be ready for a Tier2 environment**\n\n```\nNew-D365Bacpac -ExportModeTier1 -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\" -BackupDirectory c:\\Temp\\backup\\ -NewDatabaseName Testing1 -BacpacFile C:\\Temp\\Bacpac\\Testing1.bacpac\n```\n\n*This will backup the db database from the localhost server.*\n\n*It will restore the backup back into the localhost server with a new name \"Testing1\".*\n\n*It will clean up the Testing1 database for objects that cannot exist in Azure DB.*\n\n*It will start the sqlpackage.exe file and export a valid bacpac file.*\n\n*It will delete the Testing1 database on the localhost server.*\n\n### **Generate a bacpac file from a Tier2 environment. As an export / backup file only**\n\n```\nNew-D365Bacpac -ExportModeTier2 -DatabaseServer dbserver1.database.windows.net -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\" -BacpacFile C:\\Temp\\Bacpac\\Testing1.bacpac -ExportOnly\n```\n\n*This will export an bacpac file directly from the db database from the Azure db instance at dbserver1.database.windows.net.*\n\n### **Generate a bacpac file from a Tier2 environment to be ready for a Tier1 environment**\n\n```\nNew-D365Bacpac -ExportModeTier2 -DatabaseServer dbserver1.database.windows.net -DatabaseName AxDB -SqlUser User123 -SqlPwd \"Password123\" -NewDatabaseName Testing1 -BacpacFile C:\\Temp\\Bacpac\\Testing1.bacpac\n```\n\n*This will create a copy of the db database in the Azure db instance at dbserver1.database.windows.net.*\n\n*It will clean up the Testing1 database for objects that cannot exist in SQL Server.*\n\n*It will start the sqlpackage.exe file and export a valid bacpac file.*\n\n*It will delete the Testing1 database in the Azure db instance at dbserver1.database.windows.net.*\n\n### **Import bacpac file into Tier1**\n```\nImport-D365Bacpac -ImportModeTier1 -BacpacFile \"C:\\temp\\uat.bacpac\" -NewDatabaseName \"ImportedDatabase\"\n```\n*This will import into the registered sql server and create a new **\"ImportedDatabase\"** database.*\n\n*It will import the bacpac file **\"C:\\temp\\uat.bacpac\"** and prepare the database for D365.*\n\n### **List all the database connection details for an environment**\n\n```\nGet-D365DatabaseAccess\n```\n\n*This will show database connection details that D365FO is configured with*\n\n### **Decrypt and store a copy of the web.config file from the AOS**\n\n```\nGet-D365DecryptedConfigFile -DropPath 'C:\\Temp'\n```\n\n*This will store a decrypted web.config file at c:\\temp*\n\n## **Working with Windows license / activation**\n### **Get current activation status**\n```\nGet-D365WindowsActivationStatus\n```\n\n*This will get the current Windows license and activation status for the machine. It will show how many days left before expiration and how many ReArms there is left*\n\n### **Re-arm the machine and restart it when done**\n```\nInvoke-D365ReArmWindows -Restart\n```\n\n*This will try to rearm the Windows license and will only work if you have retries left. Will restart afterwards.*\n\n\n\n### **Sync the database like Visual Studio**\n\n```\nInvoke-D365DBSync\n```\n\n*This utilizes the same mechanism as Visual Studio just in PowerShell and runs the entire synchronization process.* \n\n\n## **Handling D365 environment**\n\n### **Get current state of D365FO services of machine**\n```\nGet-D365Environment\n```\n\n*Will list the status of all D365 services on the local machine*\n\n### **Get current state of D365 services on \"TEST-SB-AOS-1\" and \"TEST-SB-AOS-2\"**\n```\nGet-D365Environment -ComputerName \"TEST-SB-AOS1\",\"TEST-SB-AOS2\" -All\n```\n\n*Will list the status of all D365 services on the specified machines*\n\n### **Stop all D365FO services on machine**\n```\nStop-D365Environment\n```\n\n*Will stop all D365 services on the local machine. Will report current status for all services*\n\n### **Stop all D365FO services on \"TEST-SB-AOS-1\" and \"TEST-SB-AOS-2\"**\n```\nStop-D365Environment -ComputerName \"TEST-SB-AOS1\",\"TEST-SB-AOS2\" -All\n```\n\n*Will stop all D365 services on the the specified machines. Will report current status for all services*\n\n### **Start all D365FO services on machine**\n```\nStart-D365Environment\n```\n\n*Will start all D365 services on the local machine. Will report current status for all services*\n\n### **Start all D365FO services on \"TEST-SB-AOS-1\" and \"TEST-SB-AOS-2\"**\n\n```\nStart-D365Environment -ComputerName \"TEST-SB-AOS1\",\"TEST-SB-AOS2\" -All\n```\n\n*Will start all D365 services on the the specified machines. Will report current status for all services*\n\n### **Get all exposed D365FO services**\n\n```\nGet-ExposedService -ClientId \"YouClientIdFromAppRegistration\" -ClientSecret \"TheSecretFromTheAppRegistration\"\n```\nWill return a json containing the exposed services of the D365FO.\nIt is possible to provide \n\n- Authority [Defaulted to current instance identity provider]\n- D365FO [Defaulted to current D365FO Enviroment]\n\n### **Create self-signed certificates and configure AOS WIF trusted authorities**\n```\nInitialize-D365TestAutomationCertificate\n```\nCreates a new self signed certificate for automated testing and reconfigures the AOS Windows Identity Foundation configuration to trust the certificate\n\n## **Fix misc issues**\n### **Get Offline Authentication Administrator Email**\n\n```\nGet-D365OfflineAuthenticationAdminEmail\n```\n\n*Will display the current registered account as Offline Authentication Administrator*\n\n### **Set Offline Authentication Administrator Email**\n```\nSet-D365OfflineAuthenticationAdminEmail -Email \"admin@contoso.com\"\n\n```\n\n*Will update the Offline Authentication Administrator registration to \"admin@contoso.com\"*\n\n### **Get ClickOnce configuration**\n```\nGet-D365ClickOnceTrustPrompt\n```\n\n*This will get the current ClickOnce trust prompt configuration on the machine*\n\n### **Set ClickOnce configuration**\n```\nSet-D365ClickOnceTrustPrompt\n```\n\n*This will set the necessary ClickOnce trust prompt configuration on the machine*\n\n### **Get the Deployable Packages cleanup retention **\n```\nGet-D365SDPCleanUp\n```\n*This will display the current retention that is configured on the server. \nIf the result is empty it means that this has never been configured.*\n\n### **Set the Deployable Packages cleanup retention **\n```\nSet-D365SDPCleanUp -NumberOfDays 10\n```\n*This either create or update the cleanup retention in the registry and set \nit to 10 days.*\n\n***Notes: Please note that the Set-D365SDPCleanUp requires elevated permissions to work.***\n\n## **Work with packages, label files, language and labels**\n\n### **Get all installed packages on the machine**\n```\nGet-D365InstalledPackage\n```\n*Gets all installed packages on the system/machine*\n\n### **Get installed package by searching for a name**\n```\nGet-D365InstalledPackage -Name \"ApplicationSuite\"\n```\n*Gets the \"ApplicationSuite\" package*\n\n### **Get all label files for a installed package**\n\n```\nGet-D365InstalledPackage -Name \"ApplicationSuite\" | Get-D365PackageLabelFile -Language \"en-US\"\n```\n*Gets all the \"en-US\" resource / label files from the ApplicationSuite package*\n\n### **Get label files by searching for a name**\n\n```\nGet-D365InstalledPackage -Name \"ApplicationSuite\" | Get-D365PackageLabelFile -Language \"en-US\" -Name \"PRO\"\n```\n*Gets the PRO resource / label file from the \"ApplicationSuite\" package with the language \"EN-US\"*\n\n### **Get all label names and values from a label file**\n```\nGet-D365InstalledPackage -Name \"ApplicationSuite\" | Get-D365PackageLabelFile -Language \"en-US\" -Name \"PRO\" | Get-D365Label\n```\n*Gets all label details from the PRO resource / label file from the \"ApplicationSuite\" package with the language \"EN-US\"*\n\n### **Get label details by searching for a name**\n```\nGet-D365InstalledPackage -Name \"ApplicationSuite\" | Get-D365PackageLabelFile -Language \"*\" -Name \"PRO\" | Get-D365Label -Name \"@PRO505\"\n```\n*Gets the \"@PRO505\" label details from the \"PRO\" resource / label file from the \"ApplicationSuite\" package, **across all languages***\n\n### **Get label details by search for a value**\n```\nGet-D365InstalledPackage -Name \"ApplicationSuite\" | Get-D365PackageLabelFile -Language \"en-US\" | Get-D365Label -Value \"*qty*\" -IncludePath\n```\n*Gets all \"en-US\" labels where the value contains \"*qty*\" from the \"ApplicationSuite\" package, **across all resource / label files***\n\n### **Execute SysFlushAod class**\n\n```\nInvoke-D365SysFlushAodCache\n```\n*Will execute a web call to the SysRunnerClass with the name SysFlushAod class and have the class executed*\n\n### **Call the Table Browser**\n\n```\nInvoke-D365TableBrowser -TableName SalesTable -Company \"USMF\"\n\n```\n*Will call the Table Browser in the web browser and display all data from the SalesTable within the \"USMF\" company*\n\n### **Execute runnable class**\n\n```\nInvoke-D365SysRunnerClass -ClassName SysDBInformation -Company USMF\n\n```\n*Will execute a web call to the SysRunnerClass with the SysDBInformation as the parameter and have the class executed against the USMF company*\n\n## **Work with tables, fields and ids**\n### **Look up table details by id**\n\n```\nGet-D365Table -Id 10347\n```\n*Will get the details for the table with the id 10347*\n\n### **Look up table details by searching for a name**\n\n```\nGet-D365Table -Name CustTable\n```\n*Will get the details for the CustTable*\n\n### **Look up field details by TableId**\n\n```\nGet-D365TableField -TableId 10347\n```\n\n*Will get all fields and details for these fields for the table with id 10347*\n\n### **Look up field details by searching for a table name**\n\n```\nGet-D365TableField -TableName CustTable\n```\n*Will get all fields and details for these fields for the table CustTable*\n\n### **Get field details by TableId and FieldId**\n```\nGet-D365TableField -TableId 10347 -FieldId 175\n```\n*Will get the details for the field with id 175 that belongs to the table with id 10347*\n\n### **Get field details by TableId and by searching for a field name*\n\n```\nGet-D365TableField -TableId 10347 -Name \"VAT*\"\n```\n*Will get the details for all fields that fits the search \"VAT*\" that belongs to the table with id 10347*\n\n### **Get field details by searching for a field name across all tables**\n```\nGet-D365TableField -Name AccountNum -SearchAcrossTables\n```\n*Will search for the AccountNum field across all tables.*\n\n## **Working with Azure Storage account**\n\n### **Get all files from an Azure Storage account**\n```\nGet-D365AzureStorageFile -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Blobname \"backupfiles\"\n```\n\n*Get all files stored inside the **\"backupfiles\"** container / blob in the **\"miscfiles\"** storage account*\n\n### **Upload a file to an Azure Storage account**\n\n```\nInvoke-D365AzureStorageUpload -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Blobname \"backupfiles\" -Filepath C:\\temp\\bacpac\\UAT_20180701.bacpac -DeleteOnUpload\n```\n\n*This will upload the **\"UAT_20180701.bacpac\"** file to the specified Azure Storage Account and delete it when completed*\n\n### **Download a file from an Azure Storage account**\n\n```\nInvoke-D365AzureStorageDownload -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Blobname \"backupfiles\" -FileName \"UAT_20180701.bacpac\" -Path \"c:\\temp\" \n```\n*This will download the **\"UAT_20180701.bacpac\"** file from the Azure Storage Account and store it in \"c:\\temp\\UAT_20180701.bacpac\"*\n\n## **Working with .NET classes and methods**\n### **Get .NET class details by searching for a class name**\n```\nGet-D365DotNetClass -Name \"ERText*\"\n```\n\n*This will search across **all** assembly files (\\*.dll) located in the package directory for any class that fits the search \"**ERText\\***\"*\n\n### **Get .NET class details by searching for a class name and searching for a file name**\n```\nGet-D365DotNetClass -Name \"ERText*\" -Assembly \"*LocalizationFrameworkForAx.dll*\"\n```\n\n*This will search across assembly files (\\*.dll) that fits the search \"\\*LocalizationFrameworkForAx.dll\\*\", located in the package directory for any class that fits the search \"**ERText\\***\"*\n\n### **Get all methods available from an assembly**\n```\nGet-D365DotNetMethod -Assembly \"C:\\AOSService\\PackagesLocalDirectory\\ElectronicReporting\\bin\\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll\"\n```\n\n*This will search for all methods, across **all** classes, that exists inside the specified assembly file*\n\n## **Working with installing binary updates, X++ hotfixes and 3. party ISV solutions**\n\n### **Installation of binary updates**\n```\nInvoke-D365SDPInstall -Path C:\\DeployablePackages -Command RunAll\n```\n\n*This will execute the generate, import and execute steps in correct order. The cmdlet expects the path \"C:\\DeployablePackages\" to be the extracted directory from a package*\n\n### **Installation of 3. party ISV module - DevInstall**\n```\nInvoke-D365SDPInstall -Path C:\\DeployablePackages -DevInstall\n```\n*This will execute the **\"devinstall\"** mode. The cmdlet expects the path \"C:\\DeployablePackages\" to be the extracted directory from a package*\n\n### **Installation of 3. party ISV module - QuickInstall**\n```\nInvoke-D365SDPInstall -Path C:\\DeployablePackages -QuickInstall\n```\n*This will execute the **\"QuickInstall\"** mode. The cmdlet expects the path \"C:\\DeployablePackages\" to be the extracted directory from a package*\n\n\n### **Installation of X++ hotfix**\n```\nInvoke-D365SCDPBundleInstall -Path \"c:\\temp\\HotfixPackageBundle.axscdppkg\"\n```\n*This will execute the **\"install\"** mode without tfs / vsts parameters.*\n\n## **Working with maintenance mode**\n\n### **Enable maintenance mode**\n```\nEnable-D365MaintenanceMode\n```\n*This will put the environment into maintenance mode / state. Normally used when changing license configuration.*\n\n### **Disable maintenance mode**\n```\nDisable-D365MaintenanceMode\n```\n*This will put the environment back into operation mode / state. Normally used when changing license configuration.\n**Note: You might need to stop and start your entire environment when done.***\n\n## **Working with installed services and topology files**\n\n### **Get all installed services**\n\n```\nGet-D365InstalledService\n```\n*This will get all the installed services based on the installation logs.\n**Note: The cmdlet mimics the AxUpdateInstaller.exe -list command that also only reads the logs files***\n\n### **Create a new topology file and update it with ALMService,AOSService,BIService**\n```\nNew-D365TopologyFile -Path C:\\Temp\\DefaultTopologyData.xml -Services \"ALMService\",\"AOSService\",\"BIService\" -NewPath C:\\temp\\CurrentTopology.xml\n```\n*This will read the \"DefaultTopologyData.xml\" file and update it with ALMService, AOSService and BIService*\n\n### **Create a new topology file based on installed services**\n```\n$Services = @(Get-D365InstalledService | ForEach-Object {$_.Servicename})\nNew-D365TopologyFile -Path C:\\Temp\\DefaultTopologyData.xml -Services $Services -NewPath C:\\temp\\CurrentTopology.xml\n```\n*This will read the \"DefaultTopologyData.xml\" file and update it with the list of services from Get-D365InstalledService output*\n\n## **Working with hotfixes**\n### **Get all installed hotfixes**\n```\nGet-D365InstalledHotfix\n```\n*This will get all installed hotfixes on the machine and display all relevant information*\n\n### **Get all installed hotfixes for specific module**\n```\nGet-D365InstalledHotfix -Model \"*retail*\"\n```\n*This will get all installed hotfixes that relates to models with retail in their name on the machine and display all relevant information*\n\n### **Get all installed hotfixes for specific module and with specific KB number**\n```\nGet-D365InstalledHotfix -Model \"*retail*\" -KB \"*43*\"\n```\n*This will get all installed hotfixes that relates to models with retail in their name and where the KB number must contain **\"43\"** on the machine and display all relevant information*\n\n## **Working with models**\n### **Import a model file**\n```\nInvoke-D365ModelUtil -Path c:\\temp\\ApplicationSuiteModernDesigns_App73.axmodel\n```\n*This will import the **\"c:\\temp\\ApplicationSuiteModernDesigns_App73.axmodel\"** into the environment.*\n\n***Note: Please note that you have to compile the application and run a db sync afterwards.***\n\n## **Working with environment configurations**\n### **Initialize the D365FO.Tools configuration store**\n```\nInitialize-D365Config\n```\n*This will create the default configuration objects and set them to default values*\n\n### **Add an environment configuration**\n```\nAdd-D365EnvironmentConfig -Name \"UAT\" -URL \"https://usnconeboxax1aos.cloud.onebox.dynamics.com/?cmp=USMF\" -Company \"USMF\"\n```\n*This will add en entry named **\"UAT\"** with the **URL** and **Company** parameters.*\n\n***Notes: This is the minimum you need to enabled a personal workstation to utilize Invoke-D365TableBrowser or Invoke-D365SysRunnerClass***\n\n### **Select an environment configuration as active**\n```\nSet-D365ActiveEnvironmentConfig -Name \"UAT\"\n```\n*This will get the environment details that is named UAT and put that into the active environment configuration.*\n\n***Notes: You **MUST** restart the powershell session before using any cmdlets that depend on the configuration change.***\n\n### **Enabling the workstation mode**\n```\nSet-D365WorkstationMode -Enabled $true\n```\n*This will configure the module to be capable of running some of the cmdlets from a personal workstation tha is not an D365 environment*\n\n***Notes: You **MUST** restart the powershell session before using any cmdlets that depend on the configuration change.***\n\n### **List all environment configurations**\n```\nGet-D365EnvironmentConfig\n```\n*This will show all stored environment configurations*\n\n### **Get the active environment configuration**\n```\nGet-D365ActiveEnvironmentConfig\n```\n*This will the entire hashtable containing all the environment details*\n\n### **Get the SqlPassword from the active environment configuration**\n```\n(Get-D365ActiveEnvironmentConfig).SqlPwd\n```\n*This will only return the SqlPwd value from the active configuration*\n\n***Notes: On a Tier 2 MS hosted environment we actually load the SqlUser and SqlPassword into memory. So when calling cmdlets that require SqlUser and SqlPassword it is already filled out.***\n\n## **Working with Azure Storage Account configuration**\n### **Add an Azure Storage Account configuration**\n```\nAdd-D365AzureStorageConfig -Name \"UAT-Exports\" -AccountId \"1234\" -AccessToken \"dafdfasdfasdf\" -Blob \"testblob\"\n```\n*This will add en entry named **\"UAT-Exports\"** with the AccountId **1234**, AccessToken **dafdfasdfasdf** and Blob **testblob** parameters.*\n\n### **Select an Azure Storage Account configuration as active**\n```\nSet-D365ActiveAzureStorageConfig -Name \"UAT-Exports\"\n```\n*This will get the environment details that is named **UAT-Exports** and put that into the active Azure Storage Account configuration.*\n\n***Notes: You **MUST** restart the powershell session before using any cmdlets that depend on the configuration change.***\n\n### **List all Azure Storage Account configurations**\n```\nGet-D365AzureStorageConfig\n```\n*This will show all stored Azure Storage Account configurations*\n\n### **Get the active Azure Storage Account configuration**\n```\nGet-D365ActiveAzureStorageConfig\n```\n*This will the entire hashtable containing all the Azure Storage Account details*\n\n## **Working with AOT objects**\n### **Search for all AxClasses in a package**\n```\nGet-D365AOTObject -ObjectType AxClass -Path \"C:\\AOSService\\PackagesLocalDirectory\\ApplicationFoundation\"\n```\n*This will search for all AxClasses in the ApplicationFoundation package*\n\n### **Search for specific AxClass in a package**\n```\nGet-D365AOTObject -Name \"*flush*\" -ObjectType AxClass -Path \"C:\\AOSService\\PackagesLocalDirectory\\ApplicationFoundation\"\n```\n*This will search for all AxClasses in the ApplicationFoundation package that matches the search \"\\*flush\\*\"*\n"
  },
  {
    "path": "wiki/Open-the-path-where-D365FO.Tools-is-installed.md",
    "content": "Execute below command in powershell and an explorer window will open in the correct path\n\n```\nexplorer.exe (Split-Path (Get-Module d365fo.tools).Path -Parent)\n```"
  },
  {
    "path": "wiki/Run-a-runnable-class.md",
    "content": "**You want to execute / run a runnable class**\n\n```\nInvoke-D365SysRunnerClass -ClassName SysDBInformation\n```\n*This will start a web browser and have it call the SysRunnerClass menu item with the SysDBInformation name of a runnable class*\n\n```\nInvoke-D365SysRunnerClass -ClassName SysDBInformation -Company USMF\n```\n*This will start a web browser and have it call the SysRunnerClass menu item with the SysDBInformation name of a runnable class and only execute it against the USMF company*\n\n**Want to execute the SysFlushAod class**\n```\nInvoke-D365SysFlushAodCache\n```\n*This will start a web browser and have it call the SysRunnerClass menu item with the SysFlushAod name as the runnable class to execute*"
  },
  {
    "path": "wiki/Troubleshoot.md",
    "content": "We appreciate you taking the time to read up on how to troubleshoot issues with the d365fo.tools. Ideally, this will enable you to get to a solution for your issue on your own. If not, it will still help you gather the information needed to get help from others.\n\n> **IMPORTANT** Note that some of the information gathered may contain sensitive information. Make sure to remove any sensitive information before sharing the information with others.\n\n# General Powershell troubleshooting\n\n## Check the versions\n\n### d365fo.tools\n\nCheck whether the latest version of d365fo.tools is being used. This can be done with the `Get-Module d365fo.tools` cmdlet. If the cmdlet shows no output, add the `-ListAvailable` switch to see all versions installed on the machine. Usually the latest version will be used unless a different version is specified when loading the module. Compare the version with the latest version on [PowerShell Gallery](https://www.powershellgallery.com/packages/d365fo.tools/).\n\n> *Why is this important?* If an older version is used, a first step in troubleshooting is to update to the latest version. If the issue is already fixed in the latest version, there is no need to troubleshoot further. On the other hand, if the module needs to be on a specific older version, this is important information to know.\n\n### PowerShell\n\nCheck which version of PowerShell is being used. This can be done with the `$PSVersionTable` variable. \n\n> *Why is this important?* The module is primarily developed and tested on Windows Server environments with Windows PowerShell (i.e. PowerShell 5.1). If you are using PowerShell Core (i.e. PowerShell 6 or 7) or an older version of Windows PowerShell, there may be issues. \n\n### Other components\n\nSome cmdlets of the module rely on other components, for example SQLPackage.exe for importing and creating bacpac and dacpac files. If you know the components used by the cmdlet, check the version of those components as well.\n\n> *Why is this important?* Sometimes the issue is not with the d365fo.tools, but the component it relies on. If the component is not up to date, it may contain a bug that is already fixed in a newer version.\n\n## Use common parameters\n\nPowershell provides some common parameters that can be used with any cmdlet, see [about common parameters](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters). Often used parameters for troubleshooting are `-Verbose` and `-Debug`. Support for common parameters varies per cmdlet, but these two are supported by most. \n\n> *Why is this important?* The `-Verbose` parameter will provide additional information about what the cmdlet is doing. The `-Debug` parameter will provide even more information, including the values of variables used in the cmdlet. This can be very useful to see what is going on and where the issue is.\n\n## Additional error details\n\nEven with `-Verbose` and `-Debug`, the output of a cmdlet may not contain all the available information about an error that ocurred. To get more information, use the [automatic variable](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_automatic_variables) `$Error`. This variable contains an array of all errors that have occurred in the current session. The most recent error is `$Error[0]`, the second most recent is `$Error[1]`, etc. To get more information about an error, use the `| Format-List` cmdlet. For example, `$Error[0] | Format-List` will show the error message, the stack trace, and more.\n\n> *Why is this important?* The error message may not contain all the information needed to troubleshoot an issue. The stack trace may contain more information about where the issue occurred.\n\n## **Record a PowerShell session**\n```PS\nStart-Transcript -Path \"C:\\Temp\\PowerShellSession.log\" -Append\n```\n\n## **Gathering logs**\n```PS\nGet-PSFMessage -Errors | Format-List\nGet-PSFMessage -Errors | Format-List | Out-file c:\\temp\\errors.txt\n\nGet-PSFMessage -Level InternalComment | Format-List\nGet-PSFMessage -Level InternalComment | Format-List | out-file C:\\temp\\sqlcommands.txt\n```\n\n## **Locate the folder where the module is installed**\n```PS\nexplorer.exe (Split-Path $(Get-Module d365fo.tools -ListAvailable | Select-Object -First 1).Path -Parent)\n```\n\n## **Unsplat a hashtable to a string with parameters**\n```PS\n($HashArray.Keys | ForEach-Object {\"-$($_) `\"$($HashArray.Item($_))`\"\"}) -Join \" \"\n```\n\n## **Debug**\nFor general PowerShell debug information, see [How to debug scripts in Windows PowerShell ISE](https://docs.microsoft.com/en-us/powershell/scripting/windows-powershell/ise/how-to-debug-scripts-in-windows-powershell-ise).\n\nTo debug a cmdlet, first make sure the module is [loaded with the individual files](Load-individual-files-or-dot-source-the-files). Then open the .ps1 file of the cmdlet in PowerShell ISE and set a breakpoint. Finally, call the cmdlet."
  },
  {
    "path": "wiki/Tutorial-Import-Module.md",
    "content": "﻿# **Import the d365fo.tools module**\n\nThis tutorial will show you how to import the d365fo.tools on a machine where you already installed the d365fo.tools. \n\nYou need to import / load the d365fo.tools module into PowerShell every time you need to use a command from it.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n\nPlease visit the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\n## **Start PowerShell (Run As Administrator)**\nLocate the PowerShell icon, if you don't have it on your desktop or in the task pane, we can locate it in the Windows Start Menu. Search for it or type PowerShell.\n\nYou need to right click on the PowerShell icon and select the \"Run As Administrator\" option for the menu.\n\n[[images/tutorials/First-Time-Start-PowerShell-Administrator.gif]]\n\n## **Start PowerShell**\nLocate the PowerShell icon, if you don't have it on your desktop or in the task pane, we can locate it in the Windows Start Menu. Search for it or type PowerShell.\n\n[[images/tutorials/First-Time-Start-PowerShell-Non-Administrator.gif]]\n\n## **Import module**\nYou need to import / load the #d365fo.to module into the current PowerShell console. Type the following command:\n\n```\nImport-Module -Name d365fo.tools\n```\n\n[[images/tutorials/Import-Module-Administrator.gif]]\n\n## **Closing comments**\nIn this tutorial we showed you how to import the d365fo.tools into your PowerShell console."
  },
  {
    "path": "wiki/Tutorial-Install-Administrator.md",
    "content": "﻿# **Install as a Administrator**\n\nThis tutorial will show you how to install the d365fo.tools on a machine where you have administrator access / privileges.\n\nIf you are **NOT** able to logon to the machine as an administrator, you should be using the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorial instead.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* Administrator privileges\n* Internet access / Internet connection\n\n## **Logon to the computer**\nYou need sign into the machine where you want to install the tools. Remember to sign in as an account with administrator privileges.\n\nIf you **don't** have an user account with administrator privileges, please follow the [Install as a Non Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorial instead.\n\n## **Start PowerShell (Run As Administrator)**\nLocate the PowerShell icon, if you don't have it on your desktop or in the task pane, we can locate it in the Windows Start Menu. Search for it or type PowerShell.\n\nYou need to right click on the PowerShell icon and select the \"Run As Administrator\" option for the menu.\n\n[[images/tutorials/First-Time-Start-PowerShell-Administrator.gif]]\n\n## **Install the d365fo.tools module**\nIn the PowerShell console/window type the following command:\n\n```\nInstall-Module -Name d365fo.tools\n```\n\n[[images/tutorials/First-Time-Install-Administrator-Install-Module.gif]]\n\nPowerShell will now connect to the internet and try to download the latest version of the d365fo.tools and its dependencies. If your machine or PowerShell installation is all fresh, you might be prompted for questions / confirmations about core PowerShell configurations.\n\nYou need to either accept or approve all the prompts, for things to work like expected. See below examples on the which prompts you can expect and what response you should fill in.\n\n### **NuGet**\nIf you want to learn about NuGet as concept, you can start here: https://en.wikipedia.org/wiki/NuGet\n\nAnswer the prompt with: **Y**\n\n[[images/tutorials/First-Time-Install-Administrator-Confirm-Nuget.gif]]\n\n### **Untrusted Repository**\nThe tools are available from PowerShellGallery. If you want to learn about PowerShellGallery, you can start here: https://docs.microsoft.com/en-us/powershell/scripting/gallery/overview?view=powershell-5.1\n\nAnswer the prompt with: **A**\n\n[[images/tutorials/First-Time-Install-Administrator-Confirm-Repository.gif]]\n\n## **Completing installation**\n[[images/tutorials/First-Time-Install-Administrator-Wait-For-Installation.gif]]\n\n## **Import module**\nWhile you just installed the d365fo.tools on the machine by following this tutorial, you will need to import or simply put, load the module into the PowerShell console, before you can use it. Type the following command:\n\n```\nImport-Module -Name d365fo.tools\n```\n\n[[images/tutorials/First-Time-Install-Administrator-Import-Module.gif]]\n\n## **Closing comments**\nIn this tutorial we showed you how to install the d365fo.tools when you have administrator privileges on machine. We highlighted some of the prompts that you might face on a freshly installed machine."
  },
  {
    "path": "wiki/Tutorial-Install-Non-Administrator.md",
    "content": "﻿# **Install as a non-Administrator**\n\nThis tutorial will show you how to install the d365fo.tools on a machine where you **don't** have administrator access / privileges. \n\nIf you are able to logon to the machine as an administrator, you should be using the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) tutorial instead.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* Internet access / Internet connection\n\n## **Logon to the computer**\nYou need sign into the machine where you want to install the tools.\n\nIf you have an user account with administrator privileges, please follow the [Install as an Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) tutorial instead.\n\n## **Start PowerShell**\nLocate the PowerShell icon, if you don't have it on your desktop or in the task pane, we can locate it in the Windows Start Menu. Search for it or type PowerShell.\n\n[[images/tutorials/First-Time-Start-PowerShell-Non-Administrator.gif]]\n\n## **Install the d365fo.tools module**\nIn the PowerShell console/window type the following command:\n\n```\nInstall-Module -Name d365fo.tools -Scope CurrentUser\n```\n[[images/tutorials/First-Time-Install-Non-Administrator-Install-Module.gif]]\n\nPowerShell will now connect to the internet and try to download the latest version of the d365fo.tools and its dependencies. If your machine or PowerShell installation is all fresh, you might be prompted for questions / confirmations about core PowerShell configurations.\n\nYou need to either accept or approve all the prompts, for things to work like expected. See below examples on the which prompts you can expect and what response you should fill in.\n\n### **NuGet**\nIf you want to learn about NuGet as concept, you can start here: https://en.wikipedia.org/wiki/NuGet\n\nAnswer the prompt with: **Y**\n\n[[images/tutorials/First-Time-Install-Non-Administrator-Confirm-Nuget.gif]]\n\n### **Untrusted Repository**\nThe tools are available from PowerShellGallery. If you want to learn about PowerShellGallery, you can start here: https://docs.microsoft.com/en-us/powershell/scripting/gallery/overview?view=powershell-5.1\n\nAnswer the prompt with: **A**\n\n[[images/tutorials/First-Time-Install-Non-Administrator-Confirm-Repository.gif]]\n\n## **Completing installation**\n[[images/tutorials/First-Time-Install-Non-Administrator-Wait-For-Installation.gif]]\n\n## **Import module**\nWhile you just installed the d365fo.tools on the machine by following this tutorial, you will need to import or simply put, load the module into the PowerShell console, before you can use it. Type the following command:\n\n```\nImport-Module -Name d365fo.tools\n```\n\n[[images/tutorials/First-Time-Install-Non-Administrator-Import-Module.gif]]\n\n## **Closing comments**\nIn this tutorial we showed you how to install the d365fo.tools when you **don't** have administrator privileges on machine. We highlighted some of the prompts that you might face on a freshly installed machine."
  },
  {
    "path": "wiki/Tutorial-List-Commands.md",
    "content": "﻿# **List available commands from d365fo.tools module**\n\nThis tutorial will show you how to list and search for commands that are available from the d365fo.tools module.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n\nPlease visit the [Install as a Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a regular (non-Admin) user](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\n## **Start PowerShell**\nLocate the PowerShell icon, if you don't have it on your desktop or in the task pane, we can locate it in the Windows Start Menu. Search for it or type PowerShell.\n\n[[images/tutorials/First-Time-Start-PowerShell-Non-Administrator.gif]]\n\n## **Import module**\nYou need to import / load the d365fo.tools module into the current PowerShell console. Type the following command:\n\n```\nImport-Module -Name d365fo.tools\n```\n\n[[images/tutorials/Import-Module-Administrator.gif]]\n\n## **List all available commands**\nIf you want to see the entire list of available commands from the d365fo.tools, you can ask PowerShell to list them for you. Type the following command:\n\n```\nGet-Command -Module d365fo.tools\n```\n\n[[images/tutorials/First-Time-List-Commands.gif]]\n\n\n## **Search for commands**\nIf you want to search for command that contains a specific word or phrase, you can ask PowerShell to search for commands in the d365fo.tools module. Type the following command:\n\n```\nGet-Command *bacpac* -Module d365fo.tools\n```\n\n[[images/tutorials/First-Time-Search-Commands.gif]]\n\n## **Closing comments**\nIn this tutorial we showed you how to list all of the functions that is part of the d365fo.tools. We also showed how you can search for a specific keyword and find all commands containing that keyword.\n"
  },
  {
    "path": "wiki/Tutorial-Show-Help.md",
    "content": "﻿# **Get help content for a command**\n\nThis tutorial will show you how to get the different kind of help content available for every command in the d365fo.tools module.\n\n## **Prerequisites**\n* Machine with D365FO installed\n* PowerShell 5.1\n* d365fo.tools module installed\n\nPlease visit the [Install as a Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) or the [Install as a Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) tutorials to learn how to install the tools.\n\n## **Start PowerShell**\nLocate the PowerShell icon, if you don't have it on your desktop or in the task pane, we can locate it in the Windows Start Menu. Search for it or type PowerShell.\n\n[[images/tutorials/First-Time-Start-PowerShell-Non-Administrator.gif]]\n\n## **Import module**\nYou need to import / load the d365fo.tools module into the current PowerShell console. Type the following command:\n\n```\nImport-Module -Name d365fo.tools\n```\n\n[[images/tutorials/Import-Module-Administrator.gif]]\n\n## **List all available commands**\nFor us to have something to work with, we need to get the list of available functions in the module. Type the following command:\n\n```\nGet-Command -Module d365fo.tools\n```\n\n[[images/tutorials/First-Time-List-Commands.gif]]\n\n## **Get help content for a specific function**\nIf you want to know more about a specific command, you can pass the name of the desired command to `Get-Help`. Type the following command:\n\n```\nGet-Help New-D365Bacpac\n```\n\n[[images/tutorials/First-Time-Show-Help.gif]]\n\n## **Get help content, including examples, for a specific function**\nThe help content for every function contains a high level explanation for each available parameter and examples. Type the following command:\n\n```\nGet-Help New-D365Bacpac -Full\n```\n\n[[images/tutorials/First-Time-Show-Help-Full.gif]]\n\n## **Get examples only, for a specific function**\nThe help content for every function contains at least 1 example on how run the function. Type the following command:\n\n```\nGet-Help New-D365Bacpac -Examples\n```\n\n[[images/tutorials/First-Time-Show-Help-Examples-Only.gif]]\n\n\n## **Closing comments**\nIn this tutorial we showed you how to list help content for a specific command, including the detailed parameter explanation and the examples."
  },
  {
    "path": "wiki/Update-users-in-environment.md",
    "content": "So you just moved your **GOLDEN** / **CONFIG** from either a local VM (**onebox**) or an Azure hosted environment to a MS hosted environment (**non-prod**)?\n\nYou just restored your **PROD** / **UAT** environment to a Azure hosted or a local VM (onebox)?\n\nNow you need to grant access (back) to your users in the restored environment and you want to do it without all the mouse clicking?\n\nLook no further!\n\nWe assume:\n* That you already did run the `Install-Modele -Name d365fo.tools` on the machine / server you will be using for this.\n* That the database has been restored and you are sitting on machine / server that either runs the SQL Server (Tier1, Azure / onebox) or a machine / server inside the same network environment as the Azure DB (Tier2 - MS hosted). \n\nFor MS hosted Tier2 environments you need have the sql username and password ready, this is found on LCS under the implementation project and the details page for the desired environment. For the other environments you don't - if you run PowerShell with \"Run As Administrator\"\n\n1. Start PowerShell (Start Menu - type powershell and click enter when you see the icon marked)\n2. Run `Import-Module d365fo.tools`\n3. Run `Set-D365Admin \"insertyouremailaddress\"`\n   - Remember that the e-mail address needs to be a valid Azure Active Directory e-mail\n   - E.g. `Set-D365Admin \"allen@contoso.com\"`\n4. Wait for the command to finish\n5. Run `Update-D365User -Email \"%youremaildomain%\"`\n   - Fill in the domain of the users that you want to update and give back access to the specific environment\n   - E.g. `Update-D365User -Email \"%contoso.com%\"`"
  },
  {
    "path": "wiki/Utilizing-the-configuration-system.md",
    "content": "The d365fo.tools module is built upon the foundation of the **PSFramework**, which enables a full blown configuration store for PowerShell modules and scripts.\n\nA very important note is that everything is being stored on **user** as default. If you want to store the different configuration on a system wide fashion that option exists, but is beyond this guide. We will create a new guide to explain how to utilize the system wide feature.\n\nWe have several configuration sub sections:\n* Environment\n* Azure Storage Account\n* Azure Logic App\n\n## **Environment Configuration Store**\nThe environment configuration store is a multi array store, that can store different environment details, per environment, for your convenience.\n\nThe SqlUser & SqlPwd parameters are designed to support you when working on a Tier 2 environment and you don't want to have to either save your scripts containing your Sql credentials or you don't want to look these things up over and over logging into LCS.\n\nThe TfsUri parameter is designed to support a developer working with hotfixes and installation, that needs to check in code against VSTS / Azure DevOps.\n\nThe Url parameter is designed to support you on a workstation that wants to execute table browser and runnable classes against any D365 environment where you're credentials have access.\n\n**Available cmdlets / functions**\n* Add-D365EnvironmentConfig\n* Get-D365EnvironmentConfig\n* Get-D365ActiveEnvironmentConfig\n* Set-D365ActiveEnvironmentConfig\n\n### **Add-D365EnvironmentConfig** \n`Add-D365EnvironmentConfig` is used to register a new environment and all its details. Please read more about the details of the cmdlet in the docs or `Get-Help Add-D365EnvironmentConfig`\n\nIt is **not** necessary to fill in all the details when using the `Add-D365EnvironmentConfig`\n\n**Example on how to fill out the details for every parameter.**\nThis will create a environment configuration that is stored with the name \"TEST\"\n\n```\n$params = @{}\n$params.URL = (Get-D365Url).Url\n$params.SqlUser = \"sqladmin\"\n$params.SqlPwd = \"afafKHkhke\"\n$params.Company = \"DAT\"\n$params.TfsUri = (Get-D365TfsUri).TfsUri\nAdd-D365EnvironmentConfig -Name TEST @params\n```\n\n### **Get-D365EnvironmentConfig** \n`Get-D365EnvironmentConfig` is used to show all the registered environments and their details. Please read more about the details of the cmdlet in the docs or `Get-Help Get-D365EnvironmentConfig`\n\n**Example on how to list all environments**\n\n```\nGet-D365EnvironmentConfig\n\nName    : TEST\nTfsUri  : https://projectname.visualstudio.com/\nURL     : https://usnconeboxax1aos.cloud.onebox.dynamics.com/\nCompany : DAT\nSqlUser : sqladmin\nSqlPwd  : afafKHkhke\n```\n\n### **Set-D365ActiveEnvironmentConfig**\n`Set-D365ActiveEnvironmentConfig` is used to register some of the in-memory variables that the module relies on, by promoting an environment configuration to the status active. It is simply done by using the name that you gave it while working with `Add-D365EnvironmentConfig` and all details will be copied over to a new set that is only used with the active environment logic. Please read more about the details of the cmdlet in the docs or `Get-Help Set-D365ActiveEnvironmentConfig`\n\n**Example on how to set a given environment af the active environment configuration**\n\n```\nSet-D365ActiveEnvironmentConfig -Name TEST\n```\n\n### **Get-D365ActiveEnvironmentConfig**\n`Get-D365ActiveEnvironmentConfig` is used to show the environment details that are registered as the active environment. Please read more about the details of the cmdlet in the docs or `Get-Help Get-D365ActiveEnvironmentConfig`\n\n**Example on how to see the current active environment and its details**\n```\nGet-D365ActiveEnvironmentConfig\n\nName                           Value\n----                           -----\nTfsUri                         https://projectname.visualstudio.com/\nURL                            https://usnconeboxax1aos.cloud.onebox.dynamics.com/\nCompany                        DAT\nSqlUser                        sqladmin\nSqlPwd                         afafKHkhke\n```"
  },
  {
    "path": "wiki/Work-with-Azure-Storage-Account.md",
    "content": "So you are working with the task of creating bacpac files and moving them between different Tiers. You did read the guide on docs.microsoft.com and found it to be cumbersome. You find it rather tricky getting the files in and out of the different environments.\n\nLook no further!\n\nWe assume:\n* You already have an active Azure Storage Account\n* You already have created the needed tokens for the Azure Storage Account\n\nYou need to have the **Azure Storage Account Id**, **Access Token** and the name of the **blob** / **container** ready. This is provided to you from https://portal.azure.com when you create the **Access Token**.\n\n1. Start PowerShell (Start Menu - type powershell and click enter when you see the icon marked)\n2. Run `Import-Module d365fo.tools`\n\n**Note:**\n\n*The following examples is working with bacpac files, but the cmdlets can easily be utilized for ANY file type you desire to work with. The cmdlets was created to ease the burden of moving files in and out of the different environments during a project.*\n\n**Listing files**\n```\nGet-D365AzureStorageFile -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Blobname \"backupfiles\"\n```\n*This will get the details of all the files stored in the **\"backupfiles\"** blob / container inside the **\"miscfiles\"** Azure Storage Account*\n\n```\nGet-D365AzureStorageFile -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Blobname \"backupfiles\" -Name \"*UAT*\"\n```\n*This will get the details of all the files where the name contains \"UAT\" that are stored in the **\"backupfiles\"** blob / container inside the **\"miscfiles\"** Azure Storage Account*\n\n**Downloading files**\n```\nInvoke-D365AzureStorageDownload -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Blobname \"backupfiles\" -FileName \"OriginalUAT.bacpac\" -Path \"c:\\temp\" \n```\n*This will download the **\"OriginalUAT.bacpac\"** file from the Azure Storage Account and store it in **\"c:\\temp\\OriginalUAT.bacpac\"**.\n\n```\nInvoke-D365AzureStorageDownload -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Blobname \"backupfiles\" -Path \"c:\\temp\" -GetLatest\n```\n*This will download the file with the latest modified datetime stamp from the Azure Storage Account and store it in **\"c:\\temp\"** - the full file path will be returned as output when done.\n\n**Uploading files**\n\n```\nInvoke-D365AzureStorageUpload -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Blobname \"backupfiles\" -Filepath \"c:\\temp\\bacpac\\UAT_20180701.bacpac\" -DeleteOnUpload\n```\n*This will upload the **\"c:\\temp\\bacpac\\UAT_20180701.bacpac\"** to the Azure Storage Account and delete the file located on the machine when the upload is completed.*\n\n**Advanced scenarios**\n\n```\nGet-D365AzureStorageFile -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Blobname \"backupfiles\" -Name \"*UAT*\" | Invoke-D365AzureStorageDownload -AccountId \"miscfiles\" -AccessToken \"xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51\" -Blobname \"backupfiles\" -Path \"c:\\temp\"\n```\n*Using the **Get-D365AzureStorageFile** cmdlet to find all files where the name contains **\"*UAT*\"**. The result from **Get-D365AzureStorageFile** is piped into the **D365AzureStorageDownload** cmdlet, that now makes sure to download all files into the **\"c:\\temp\"** directory on the machine.*"
  },
  {
    "path": "wiki/Work-with-packages,-resource---label-files,-language-and-lables.md",
    "content": "**Work with packages, label files, language and labels**\n\n```\nGet-D365InstalledPackage\n```\n*Gets all installed packages on the system/machine*\n\n```\nGet-D365InstalledPackage -Name \"ApplicationSuite\"\n```\n*Gets the \"ApplicationSuite\" package*\n\n```\nGet-D365InstalledPackage -Name \"ApplicationSuite\" | Get-D365PackageLabelFile -Language \"en-US\"\n```\n*Gets all the \"en-US\" resource / label files from the ApplicationSuite package*\n\n```\nGet-D365InstalledPackage -Name \"ApplicationSuite\" | Get-D365PackageLabelFile -Language \"en-US\" -Name \"PRO\"\n```\n*Gets the PRO resource / label file from the \"ApplicationSuite\" package with the language \"EN-US\"*\n\n```\nGet-D365InstalledPackage -Name \"ApplicationSuite\" | Get-D365PackageLabelFile -Language \"en-US\" -Name \"PRO\" | Get-D365Label\n```\n*Gets all label details from the PRO resource / label file from the \"ApplicationSuite\" package with the language \"EN-US\"*\n\n```\nGet-D365InstalledPackage -Name \"ApplicationSuite\" | Get-D365PackageLabelFile -Language \"*\" -Name \"PRO\" | Get-D365Label -Name \"@PRO505\"\n```\n*Gets the \"@PRO505\" label details from the \"PRO\" resource / label file from the \"ApplicationSuite\" package, **across all languages***\n\n```\nGet-D365InstalledPackage -Name \"ApplicationSuite\" | Get-D365PackageLabelFile -Language \"en-US\" | Get-D365Label -Value \"*qty*\" -IncludePath\n```\n\n*Gets all \"en-US\" labels where the value contains \"*qty*\" from the \"ApplicationSuite\" package, **across all resource / label files***\n\n```\nGet-D365InstalledPackage | Out-GridView -PassThru | Get-D365PackageLabelFile -Language \"da\" | Out-GridView -PassThru | Get-D365Label -IncludePath | Out-GridView \n```\n\n*You don't quite know what you are looking for and the powershell cmdlets does not feel comfortable. Use the above command to display a GridView with filtering options available. First you will have to select what package you want to work against - you can select multiple. Next GridView will make you select the specific resource / label files you want to work against, across the selected packages - you can select multiple. The last GridView will show you the results from the earlier selections and make it possible for you to filter what ever you want.*\n\n```\nGet-D365InstalledPackage | Get-D365PackageLabelFile -Language \"da\" | Get-D365Label -Value \"*antal*\" -IncludePath | Out-GridView\n```\n\n*Shows all labels that contains the \"antal\" text value, across all packages, across all resource / label files, with the language \"da\" and shows it in GridView where you can filter the entire result further for you convenience* "
  },
  {
    "path": "wiki/Work-with-tables-and-fields.md",
    "content": "So you are working with troubleshooting or maybe extending Dynamics 365 Finance & Operations.\n\n* You might have a TableId and want to know what table(name) is behind that id.\n* You might have a table(name) and want to know what TableId is behind that table name.\n* You might have a TableId and FieldId and want to know what hides behind different ids.\n* You might have a table(name) and want to know what fields are part of the table.\n* You might have part of a field(name) and want to search all tables for a matching field.\n\nLook no further!\n\nWe assume:\n* That you already did run the `Install-Modele -Name d365fo.tools` on the machine / server you will be using for this. \n* That you will be running this from a Tier 1 machine /environment or one the AOS machines / Servers in the Tier 2 environment.\n\n1. Start PowerShell (Start Menu - type powershell and click enter when you see the icon marked)\n2. Run `Import-Module d365fo.tools`\n\n**You want to search for CustTable, either by TableId or TableName**\n\n```\nGet-D365Table -Id 10347\n```\n*You only have the TableId: 10347 on your hands and your memory doesn't seem to remember that this is actually CustTable*\n\n```\nGet-D365Table -Name CustTable\n```\n*You only have the \"CustTable\" on your hands and your memory doesn't seem to remember that this is actually TableId: 10347*\n\n**You want to see all fields for CustTable, either by TableId or TableName**\n```\nGet-D365TableField -TableId 10347\n#OR\nGet-D365TableField -TableId 10347 -IncludeTableDetails | Format-Table\n```\n*You only have the TableId: 10347 on your hands and you can't remember all fields that is part of that table*\n```\nGet-D365TableField -TableName CustTable\n#OR\nGet-D365TableField -TableName CustTable -IncludeTableDetails | Format-Table\n```\n*You only have the \"CustTable\" on your hands and you can't remember all fields that is part of that table*\n\n**You want to see a specific field for CustTable, either by TableId or TableName, and either by FieldId or FieldName**\n```\nGet-D365TableField -TableId 10347 -FieldId 175\n#OR\nGet-D365TableField -TableId 10347 -Name vatnum\n```\n*You only have the TableId: 10347 on your hands and you can't the FieldId or FieldName for VATNUM*\n```\nGet-D365TableField -TableName CustTable -FieldId 175\n#OR\nGet-D365TableField -TableName CustTable -Name vatnum\n```\n*You only have the \"CustTable\" on your hands and you can't the FieldId or FieldName for VATNUM*\n\n## **You are ready to take your PowerShell skills to the next level**\n```\nGet-D365Table -Name CustTable,CustTrans | Get-D365TableField -Name Accountnum -IncludeTableDetails | Format-Table\n```\n*You want to search for a Column(name) / Field(name) across multiple **known** tables*\n\n```\nGet-D365Table -Name CustTable,CustTrans | Get-D365TableField -IncludeTableDetails | Format-Table\n```\n*You want to see all fields across multiple **known** tables*\n\n```\nGet-D365TableField -Name AccountNum -SearchAcrossTables | Get-D365TableField -IncludeTableDetails | Format-Table\n```\n*You want to search for a Column(name) / Field(name) across **all** tables and include the full details*\n\n***Note:** The first instance of Get-D365TableField finds all FieldIds with TableIds, and the second instance of Get-D365TableField is used to do the search again to have the TableName included in the result*\n\n```\nGet-D365TableField -Name \"Account*\" -SearchAcrossTables  | Format-List\n```\n*You want to search for a Column(name) / Field(name) across **all** tables*\n\n**Small teaser for the combination of Get-D365Table and Invoke-D365TableBrowser**\n\n```\nGet-D365Table -Name CustTable,CustTrans | Invoke-D365TableBrowser -Company USMF\n```\n*You want to start the table browser for **both** CustTable & CustTrans, against the USMF company*"
  },
  {
    "path": "wiki/Working-with-the-different-D365-services.md",
    "content": "So you are working on a project where you have to export/import a bacpac file from any NON-PROD environment.\n\nYou might have to login to several different servers / machines to ensure that the different D365 services are stopped / shutdown before continuing with your planned work.\n\nLook no further!\n\nWe assume:\n* That you already did run the `Install-Module -Name d365fo.tools` on the machine / server you will be using for this. \n* That you will be running this from 1 of the AOS machines / Servers in the Tier 2 environment.\n\n1. Start PowerShell (Start Menu - type powershell and click enter when you see the icon marked)\n2. Run `Import-Module d365fo.tools`\n\n\n**Tier-1 examples**\nRun `Get-D365Environment -All`\n\n*This will display the current status of all the D365 services on the machine*\n\nRun `Stop-D365Environment -All`\n\n*This stop all the D365 services on the machine. It will list the current status for all services*\n\nRun `Start-D365Environment -All`\n\n*This start all the D365 services on the machine. It will list the current status for all services*\n\n**Tier-2 examples**\nRun `Get-D365Environment -ComputerName \"TEST-SB-AOS1\",\"TEST-SB-AOS2\",\"TEST-SB-BI1\" -All`\n\n*This will display the current status of all the D365 services across all the supplied machines.*\n\nRun `Stop-D365Environment -ComputerName \"TEST-SB-AOS1\",\"TEST-SB-AOS2\",\"TEST-SB-BI1\" -All`\n\n*This stop all the D365 services across all the supplied machines. It will list the current status for all services*\n\nRun `Start-D365Environment -ComputerName \"TEST-SB-AOS1\",\"TEST-SB-AOS2\",\"TEST-SB-BI1\" -All`\n\n*This start all the D365 services across all the supplied machines. It will list the current status for all services*"
  },
  {
    "path": "wiki/_Sidebar.md",
    "content": "# **Learn**\n## **Tutorials**\n* [Install as a non-Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator)\n* [Install as a Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator)\n* [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module)\n* [List available commands from d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-List-Commands)\n* [Get help content for a command](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Show-Help)\n\n## **How To**\n* [Start, Stop and List services](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Start-Stop-List-D365FO-Services)\n* [Import users into the D365FO environment](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Import-User-Into-Db)\n* [Import external users into the D365FO environment](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Import-External-User-Into-Db)\n* [Enable users in the D365FO environment](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Enable-Users-In-Db)\n* [Update users in the D365FO environment](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Update-Users-In-Db)\n* [Provision D365FO environment to new Azure AD tenant](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Provision-Environment-Tier1)\n* [Import a bacpac file into a Tier1 environment](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Import-Bacpac-Into-Tier1)\n* [List modules / models](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-List-Models)\n* [Compile module](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Compile-Model)\n* [Install AzCopy](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Install-AzCopy)\n* [Install SqlPackage](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Install-SqlPackage)\n* [Install Nuget](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Install-Nuget)\n* [Speed up LCS download via AzCopy](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Transfer-Via-AzCopy)\n* [Download latest bacpac from LCS via AzCopy](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Download-Latest-Bacpac-From-Lcs)\n* [Register NuGet source](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Register-Nuget-Source)\n\n## **Guides**\n* [[Configure Azure Logic App]]\n* [[Fix AzureStorageConfig]]\n* [[Run a runnable class]]\n* [[Update users in environment]]\n* [[Work with Azure Storage Account]]\n* [Work with packages, resource label files, language and lables](https://github.com/d365collaborative/d365fo.tools/wiki/Work-with-packages,-resource---label-files,-language-and-lables)\n* [[Working with the different D365 services]]\n\n# **Documentation**\n\n## **Concepts**\n\n### **Automation**\n* [[Exception handling]]\n\n### **Configuration**\n* [[Configuration]]\n\n# **Contribute**\n\n## **Start Here**\n* [[Do And Do Not]]\n* [[Implementing the messaging system]]\n* [[Getting Started with GitHub]]\n* [Your First Pull Request](https://github.com/sqlcollaborative/dbatools/wiki/Your-First-Pull-Request)\n* [[Removing a file from your PR]]\n* [[Style Guide]]\n* [[Branching]]\n* [[Azure DevOps Build Configuration]]\n* [[Building-tools]]\n* [[How To Write Wiki Pages]]\n\n## **Quality Control**\n* [[Testing & QA]]\n\n## **Automated Testing**\n* [[Appveyor and tests]]\n\n## **Deprecation**\n* [[Deprecation guidelines]]\n\n## **Troubleshooting**\n* [[Troubleshoot]]\n* [[Load individual files or dot source the files]]"
  }
]